35 #include <glib/gi18n.h> 47 #include "TransactionP.h" 58 #include <qofinstance-p.h> 173 const char *trans_notes_str =
"notes";
174 const char *void_reason_str =
"void-reason";
175 const char *void_time_str =
"void-time";
176 const char *void_former_notes_str =
"void-former-notes";
177 const char *trans_is_closing_str =
"book_closing";
178 const char *doclink_uri_str =
"assoc_uri";
181 #define TRANS_DATE_DUE_KVP "trans-date-due" 182 #define TRANS_TXN_TYPE_KVP "trans-txn-type" 183 #define TRANS_READ_ONLY_REASON "trans-read-only" 184 #define TRANS_REVERSED_BY "reversed-by" 185 #define GNC_SX_FROM "from-sched-xaction" 187 #define ISO_DATELENGTH 32 190 static QofLogModule log_module = GNC_MOD_ENGINE;
206 check_open (
const Transaction *trans)
208 if (trans && 0 >= qof_instance_get_editlevel(trans))
209 PERR (
"transaction %p not open for editing", trans);
214 xaccTransStillHasSplit(
const Transaction *trans,
const Split *s)
221 #define FOR_EACH_SPLIT(trans, cmd_block) if (trans->splits) { \ 223 for (splits = (trans)->splits; splits; splits = splits->next) { \ 224 Split *s = splits->data; \ 225 if (xaccTransStillHasSplit(trans, s)) { \ 231 static inline void mark_trans (Transaction *trans);
232 void mark_trans (Transaction *trans)
234 FOR_EACH_SPLIT(trans, mark_split(s));
237 static inline void gen_event_trans (Transaction *trans);
238 void gen_event_trans (Transaction *trans)
242 for (node = trans->splits; node; node = node->next)
244 Split *s = node->data;
246 GNCLot *lot = s->lot;
259 G_DEFINE_TYPE(Transaction, gnc_transaction, QOF_TYPE_INSTANCE)
262 gnc_transaction_init(Transaction* trans)
264 ENTER (
"trans=%p", trans);
266 trans->num = CACHE_INSERT(
"");
267 trans->description = CACHE_INSERT(
"");
268 trans->common_currency = NULL;
269 trans->splits = NULL;
270 trans->date_entered = 0;
271 trans->date_posted = 0;
274 trans->txn_type = TXN_TYPE_UNCACHED;
279 gnc_transaction_dispose(GObject *txnp)
281 G_OBJECT_CLASS(gnc_transaction_parent_class)->dispose(txnp);
285 gnc_transaction_finalize(GObject* txnp)
287 G_OBJECT_CLASS(gnc_transaction_parent_class)->finalize(txnp);
297 gnc_transaction_get_property(GObject*
object,
305 g_return_if_fail(GNC_IS_TRANSACTION(
object));
307 tx = GNC_TRANSACTION(
object);
311 g_value_set_string(value, tx->num);
313 case PROP_DESCRIPTION:
314 g_value_set_string(value, tx->description);
317 g_value_take_object(value, tx->common_currency);
320 time.t = tx->date_posted;
321 g_value_set_boxed(value, &time);
323 case PROP_ENTER_DATE:
324 time.t = tx->date_entered;
325 g_value_set_boxed(value, &time);
333 case PROP_ONLINE_ACCOUNT:
337 G_OBJECT_WARN_INVALID_PROPERTY_ID(
object, prop_id, pspec);
343 gnc_transaction_set_property(GObject*
object,
351 g_return_if_fail(GNC_IS_TRANSACTION(
object));
353 tx = GNC_TRANSACTION(
object);
354 g_assert (qof_instance_get_editlevel(tx));
361 case PROP_DESCRIPTION:
368 t = (
Time64*)g_value_get_boxed(value);
371 case PROP_ENTER_DATE:
372 t = (
Time64*)g_value_get_boxed(value);
381 case PROP_ONLINE_ACCOUNT:
385 G_OBJECT_WARN_INVALID_PROPERTY_ID(
object, prop_id, pspec);
391 gnc_transaction_class_init(TransactionClass* klass)
393 GObjectClass* gobject_class = G_OBJECT_CLASS(klass);
395 gobject_class->dispose = gnc_transaction_dispose;
396 gobject_class->finalize = gnc_transaction_finalize;
397 gobject_class->set_property = gnc_transaction_set_property;
398 gobject_class->get_property = gnc_transaction_get_property;
400 g_object_class_install_property
403 g_param_spec_string(
"num",
404 "Transaction Number",
405 "The transactionNumber is an arbitrary string " 406 "assigned by the user. It is intended to be " 407 "a short 1-6 character string that is displayed " 408 "by the register. For checks, it is usually the " 409 "check number. For other types of transactions, " 410 "it can be any string.",
414 g_object_class_install_property
417 g_param_spec_string(
"description",
418 "Transaction Description",
419 "The transaction description is an arbitrary string " 420 "assigned by the user. It is usually the customer, " 421 "vendor or other organization associated with the " 426 g_object_class_install_property
429 g_param_spec_object (
"currency",
431 "The base currency for this transaction.",
435 g_object_class_install_property
438 g_param_spec_boxed(
"post-date",
440 "The date the transaction occurred.",
444 g_object_class_install_property
447 g_param_spec_boxed(
"enter-date",
449 "The date the transaction was entered.",
453 g_object_class_install_property(
456 g_param_spec_boxed(
"invoice",
457 "Invoice attached to lot",
458 "Used by GncInvoice",
462 g_object_class_install_property(
465 g_param_spec_boxed(
"from-sched-xaction",
466 "From Scheduled Transaction",
467 "Used by Scheduled Transastions to record the " 468 "originating template transaction for created " 473 g_object_class_install_property
476 g_param_spec_string (
"online-id",
478 "The online account which corresponds to this " 479 "account for OFX/HCBI import",
490 xaccInitTransaction (Transaction * trans, QofBook *book)
492 ENTER (
"trans=%p", trans);
505 g_return_val_if_fail (book, NULL);
507 trans = g_object_new(GNC_TYPE_TRANSACTION, NULL);
508 xaccInitTransaction (trans, book);
514 #ifdef DUMP_FUNCTIONS 520 xaccTransDump (
const Transaction *trans,
const char *tag)
525 printf(
"%s Trans %p", tag, trans);
526 memset(datebuff, 0,
sizeof(datebuff));
528 printf(
" Entered: %s\n", datebuff);
529 memset(datebuff, 0,
sizeof(datebuff));
531 printf(
" Posted: %s\n", datebuff);
532 printf(
" Num: %s\n", trans->num ? trans->num :
"(null)");
533 printf(
" Description: %s\n",
534 trans->description ? trans->description :
"(null)");
535 printf(
" Currency: %s\n",
537 printf(
" version: %x\n", qof_instance_get_version(trans));
538 printf(
" version_chk: %x\n", qof_instance_get_version_check(trans));
539 printf(
" editlevel: %x\n", qof_instance_get_editlevel(trans));
540 printf(
" orig: %p\n", trans->orig);
543 for (node = trans->splits; node; node = node->next)
545 printf(
"%p ", node->data);
548 for (node = trans->splits; node; node = node->next)
550 xaccSplitDump(node->data, tag);
559 GList *node, *new_list = NULL;
563 for (node = trans->splits; node; node = node->next)
568 new_list = g_list_prepend (new_list, split);
572 for (node = trans->splits; node; node = node->next)
577 new_list = g_list_prepend (new_list, split);
581 g_list_free(trans->splits);
582 trans->splits = g_list_reverse (new_list);
594 dupe_trans (
const Transaction *from)
599 to = g_object_new (GNC_TYPE_TRANSACTION, NULL);
601 CACHE_REPLACE (to->num, from->num);
602 CACHE_REPLACE (to->description, from->description);
604 to->splits = g_list_copy (from->splits);
605 for (node = to->splits; node; node = node->next)
607 node->data = xaccDupeSplit (node->data);
610 to->date_entered = from->date_entered;
611 to->date_posted = from->date_posted;
612 qof_instance_copy_version(to, from);
615 to->common_currency = from->common_currency;
621 to->inst.e_type = NULL;
624 qof_instance_copy_kvp (QOF_INSTANCE(to), QOF_INSTANCE(from));
642 to = g_object_new (GNC_TYPE_TRANSACTION, NULL);
644 to->date_entered = from->date_entered;
645 to->date_posted = from->date_posted;
646 CACHE_REPLACE (to->num, from->num);
647 CACHE_REPLACE (to->description, from->description);
648 to->common_currency = from->common_currency;
649 qof_instance_copy_version(to, from);
650 qof_instance_copy_version_check(to, from);
658 for (node = from->splits; node; node = node->next)
660 split = xaccSplitCloneNoKvp(node->data);
662 to->splits = g_list_append (to->splits, split);
664 qof_instance_set_dirty(QOF_INSTANCE(to));
676 if (g_list_length (to->splits) != g_list_length (from->splits))
678 PERR (
"Cloned transaction has different number of splits from original");
684 qof_instance_copy_kvp (QOF_INSTANCE (to), QOF_INSTANCE (from));
689 for (GList* lfrom = from->splits, *lto = to->splits; lfrom && lto;
690 lfrom = g_list_next (lfrom), lto = g_list_next (lto))
691 xaccSplitCopyKvp (lfrom->data, lto->data);
706 Transaction *to_trans;
711 to_trans = dupe_trans(from_trans);
747 gboolean change_accounts = FALSE;
750 if (!from_trans || !to_trans)
753 change_accounts = from_acc && GNC_IS_ACCOUNT(to_acc) && from_acc != to_acc;
757 g_list_free(to_trans->splits);
758 to_trans->splits = NULL;
774 for (node = from_trans->splits; node; node = node->next)
779 xaccSplitSetAccount(new_split, to_acc);
780 xaccSplitSetParent(new_split, to_trans);
791 xaccFreeTransaction (Transaction *trans)
797 ENTER (
"(addr=%p)", trans);
798 if (((
char *) 1) == trans->num)
800 PERR (
"double-free %p", trans);
806 for (node = trans->splits; node; node = node->next)
807 xaccFreeSplit (node->data);
808 g_list_free (trans->splits);
809 trans->splits = NULL;
812 CACHE_REMOVE(trans->num);
813 CACHE_REMOVE(trans->description);
816 trans->num = (
char *) 1;
817 trans->description = NULL;
818 trans->date_entered = 0;
819 trans->date_posted = 0;
822 xaccFreeTransaction (trans->orig);
827 g_object_unref(trans);
829 LEAVE (
"(addr=%p)", trans);
844 compare_split_guids (gconstpointer a, gconstpointer b)
849 if (sa == sb)
return 0;
850 if (!sa || !sb)
return 1;
857 gboolean check_guids,
858 gboolean check_splits,
859 gboolean check_balances,
860 gboolean assume_ordered)
864 if (!ta && !tb)
return TRUE;
868 PINFO (
"one is NULL");
872 if (ta == tb)
return TRUE;
880 PINFO (
"GUIDs differ");
887 PINFO (
"commodities differ %s vs %s",
893 if (ta->date_entered != tb->date_entered)
900 PINFO (
"date entered differs: '%s' vs '%s'", buf1, buf2);
904 if (ta->date_posted != tb->date_posted)
911 PINFO (
"date posted differs: '%s' vs '%s'", buf1, buf2);
918 if ((same_book && ta->num != tb->num) || (!same_book && g_strcmp0(ta->num, tb->num) != 0))
920 PINFO (
"num differs: %s vs %s", ta->num, tb->num);
924 if ((same_book && ta->description != tb->description)
925 || (!same_book && g_strcmp0(ta->description, tb->description)))
927 PINFO (
"descriptions differ: %s vs %s", ta->description, tb->description);
931 if (qof_instance_compare_kvp (QOF_INSTANCE (ta), QOF_INSTANCE (tb)) != 0)
936 frame_a = qof_instance_kvp_as_string (QOF_INSTANCE (ta));
937 frame_b = qof_instance_kvp_as_string (QOF_INSTANCE (tb));
940 PINFO (
"kvp frames differ:\n%s\n\nvs\n\n%s", frame_a, frame_b);
950 if ((!ta->splits && tb->splits) || (!tb->splits && ta->splits))
952 PINFO (
"only one has splits");
956 if (ta->splits && tb->splits)
958 GList *node_a, *node_b;
960 for (node_a = ta->splits, node_b = tb->splits;
962 node_a = node_a->next, node_b = node_b->next)
964 Split *split_a = node_a->data;
969 node_b = g_list_find_custom (tb->splits, split_a,
970 compare_split_guids);
977 PINFO (
"first has split %s and second does not",guidstr);
981 split_b = node_b->data;
983 if (!
xaccSplitEqual (split_a, split_b, check_guids, check_balances,
992 PINFO (
"splits %s and %s differ", str_a, str_b);
997 if (g_list_length (ta->splits) != g_list_length (tb->splits))
999 PINFO (
"different number of splits");
1027 if (!guid || !book)
return NULL;
1038 gnc_numeric imbal = gnc_numeric_zero();
1039 if (!trans)
return imbal;
1041 ENTER(
"(trans=%p)", trans);
1044 FOR_EACH_SPLIT(trans, imbal =
1058 MonetaryList *imbal_list = NULL;
1059 gnc_numeric imbal_value = gnc_numeric_zero();
1060 gboolean trading_accts;
1062 if (!trans)
return imbal_list;
1064 ENTER(
"(trans=%p)", trans);
1076 FOR_EACH_SPLIT(trans,
1078 gnc_commodity *commodity;
1080 if (trading_accts &&
1091 imbal_list = gnc_monetary_list_add_value(imbal_list,
1092 trans->common_currency,
1095 imbal_list = gnc_monetary_list_add_value(imbal_list, commodity,
1110 imbal_list = gnc_monetary_list_add_value(imbal_list,
1111 trans->common_currency,
1119 LEAVE(
"(trans=%p), imbal=%p", trans, imbal_list);
1126 MonetaryList *imbal_list;
1128 gnc_numeric imbal = gnc_numeric_zero();
1129 gnc_numeric imbal_trading = gnc_numeric_zero();
1131 if (trans == NULL)
return FALSE;
1138 FOR_EACH_SPLIT(trans,
1164 result = imbal_list == NULL;
1173 gnc_numeric total = gnc_numeric_zero ();
1174 if (!trans || !acc)
return total;
1188 gnc_numeric total = gnc_numeric_zero ();
1189 if (!trans || !acc)
return total;
1194 total = gnc_numeric_add_fixed(
1201 xaccTransGetRateForCommodity(
const Transaction *trans,
1202 const gnc_commodity *split_com,
1203 const Split *split, gnc_numeric *rate)
1206 gnc_commodity *trans_curr;
1208 if (trans == NULL || split_com == NULL || split == NULL)
1215 *rate = gnc_numeric_create (1, 1);
1219 for (splits = trans->splits; splits; splits = splits->next)
1221 Split *s = splits->data;
1222 gnc_commodity *comm;
1224 if (!xaccTransStillHasSplit (trans, s))
continue;
1250 xaccTransGetAccountConvRate(
const Transaction *txn,
const Account *acc)
1252 gnc_numeric amount, value, convrate;
1255 gboolean found_acc_match = FALSE;
1264 return gnc_numeric_create(1, 1);
1266 for (splits = txn->splits; splits; splits = splits->next)
1269 gnc_commodity *split_commod;
1273 if (!xaccTransStillHasSplit(txn, s))
1277 if (! (split_acc == acc ||
1281 found_acc_match = TRUE;
1290 PWARN(
"How can amount be nonzero and value be zero?");
1301 if (found_acc_match)
1302 return gnc_numeric_zero();
1304 PERR(
"Cannot convert transaction -- no splits with proper conversion ratio");
1306 return gnc_numeric_create (100, 100);
1314 Split *last_split = NULL;
1319 for (node = trans->splits; node; node = node->next)
1321 Split *split = node->data;
1323 if (!xaccTransStillHasSplit(trans, split))
1350 return trans ? trans->common_currency : NULL;
1355 find_new_rate(Transaction *trans, gnc_commodity *curr)
1358 gnc_numeric rate = gnc_numeric_zero();
1359 for (node = trans->splits; node != NULL; node = g_list_next (node))
1361 Split *split = GNC_SPLIT(node->data);
1362 gnc_commodity *split_com =
1378 split_set_new_value(Split* split, gnc_commodity *curr, gnc_commodity *old_curr,
1381 gnc_commodity *split_com =
1409 gnc_commodity *old_curr = trans->common_currency;
1410 if (!trans || !curr || trans->common_currency == curr)
return;
1413 trans->common_currency = curr;
1414 if (old_curr != NULL && trans->splits != NULL)
1416 gnc_numeric rate = find_new_rate(trans, curr);
1419 FOR_EACH_SPLIT(trans, split_set_new_value(s, curr, old_curr, rate));
1427 qof_instance_set_dirty(QOF_INSTANCE(trans));
1451 trans->orig = dupe_trans (trans);
1466 qof_instance_set_destroying(trans, TRUE);
1472 destroy_gains (Transaction *trans)
1475 for (node = trans->splits; node; node = node->next)
1477 Split *s = node->data;
1478 if (!xaccTransStillHasSplit(trans, s))
1481 if (GAINS_STATUS_UNKNOWN == s->gains) xaccSplitDetermineGainStatus(s);
1482 if (s->gains_split && (GAINS_STATUS_GAINS & s->gains_split->gains))
1484 Transaction *t = s->gains_split->parent;
1486 s->gains_split = NULL;
1492 do_destroy (Transaction *trans)
1501 destroy_gains (trans);
1516 for (node = trans->splits; node; node = node->next)
1518 Split *s = node->data;
1519 if (s && s->parent == trans)
1524 for (node = trans->splits; node; node = node->next)
1526 Split *s = node->data;
1527 if (s && s->parent == trans)
1529 xaccSplitCommitEdit(s);
1532 g_list_free (trans->splits);
1533 trans->splits = NULL;
1534 xaccFreeTransaction (trans);
1541 static int scrub_data = 1;
1542 void xaccEnableDataScrubbing(
void)
1546 void xaccDisableDataScrubbing(
void)
1552 static gboolean was_trans_emptied(Transaction *trans)
1554 FOR_EACH_SPLIT(trans,
return FALSE);
1558 static void trans_on_error(Transaction *trans,
QofBackendError errcode)
1566 PWARN(
"Another user has modified this transaction\n" 1567 "\tjust a moment ago. Please look at their changes,\n" 1568 "\tand try again, if needed.\n");
1572 gnc_engine_signal_commit_error( errcode );
1575 static void trans_cleanup_commit(Transaction *trans)
1577 GList *slist, *node;
1584 slist = g_list_copy(trans->splits);
1585 for (node = slist; node; node = node->next)
1587 Split *s = node->data;
1597 ed.idx = g_list_index(trans->splits, s);
1598 trans->splits = g_list_remove(trans->splits, s);
1602 if (s->parent == trans)
1608 xaccSplitCommitEdit(s);
1618 PINFO (
"get rid of rollback trans=%p", trans->orig);
1619 xaccFreeTransaction (trans->orig);
1627 qof_instance_decrease_editlevel(trans);
1628 g_assert(qof_instance_get_editlevel(trans) == 0);
1630 gen_event_trans (trans);
1638 ENTER (
"(trans=%p)", trans);
1642 LEAVE(
"editlevel non-zero");
1649 qof_instance_increase_editlevel(trans);
1651 if (was_trans_emptied(trans))
1652 qof_instance_set_destroying(trans, TRUE);
1676 if (g_getenv(
"GNC_AUTO_SCRUB_LOTS") != NULL)
1684 if (0 == trans->date_entered)
1686 trans->date_entered =
gnc_time(NULL);
1687 qof_instance_set_dirty(QOF_INSTANCE(trans));
1690 trans->txn_type = TXN_TYPE_UNCACHED;
1696 LEAVE (
"(trans=%p)", trans);
1699 #define SWAP_STR(a, b) do { const char *tmp = (a); (a) = (b); (b) = tmp; } while (0); 1700 #define SWAP(a, b) do { gpointer tmp = (a); (a) = (b); (b) = tmp; } while (0); 1713 GList *node, *onode;
1717 int num_preexist, i;
1726 if (!qof_instance_get_editlevel (QOF_INSTANCE (trans)))
return;
1727 if (qof_instance_get_editlevel (QOF_INSTANCE (trans)) > 1) {
1728 qof_instance_decrease_editlevel (QOF_INSTANCE (trans));
1732 ENTER (
"trans addr=%p\n", trans);
1739 SWAP_STR(trans->num, orig->num);
1740 SWAP_STR(trans->description, orig->description);
1741 trans->date_entered = orig->date_entered;
1742 trans->date_posted = orig->date_posted;
1743 SWAP(trans->common_currency, orig->common_currency);
1744 qof_instance_swap_kvp (QOF_INSTANCE (trans), QOF_INSTANCE (orig));
1752 num_preexist = g_list_length(orig->splits);
1753 slist = g_list_copy(trans->splits);
1754 for (i = 0, node = slist, onode = orig->splits; node;
1755 i++, node = node->next, onode = onode ? onode->next : NULL)
1757 Split *s = node->data;
1762 if (i < num_preexist && onode)
1764 Split *so = onode->data;
1766 xaccSplitRollbackEdit(s);
1767 SWAP_STR(s->action, so->action);
1768 SWAP_STR(s->memo, so->memo);
1769 qof_instance_copy_kvp (QOF_INSTANCE (s), QOF_INSTANCE (so));
1770 s->reconciled = so->reconciled;
1771 s->amount = so->amount;
1772 s->value = so->value;
1774 s->gains_split = so->gains_split;
1776 s->date_reconciled = so->date_reconciled;
1777 qof_instance_mark_clean(QOF_INSTANCE(s));
1784 trans->splits = g_list_remove(trans->splits, s);
1789 xaccSplitRollbackEdit(s);
1790 trans->splits = g_list_remove(trans->splits, s);
1806 for (node = orig->splits; node; node = node->next)
1807 xaccFreeSplit(node->data);
1808 g_list_free(orig->splits);
1809 orig->splits = NULL;
1816 if (qof_backend_can_rollback (be))
1825 while (ERR_BACKEND_NO_ERR != errcode);
1827 qof_backend_rollback_instance (be, &(trans->inst));
1842 LEAVE (
"deleted trans addr=%p\n", trans);
1845 if (ERR_BACKEND_NO_ERR != errcode)
1847 PERR (
"Rollback Failed. Ouch!");
1856 xaccFreeTransaction (trans->orig);
1859 qof_instance_set_destroying(trans, FALSE);
1862 qof_instance_decrease_editlevel(trans);
1866 gen_event_trans (trans);
1868 LEAVE (
"trans addr=%p\n", trans);
1874 return trans ? (0 < qof_instance_get_editlevel(trans)) : FALSE;
1877 #define SECS_PER_DAY 86400 1896 order_by_int64_or_string (
const char* a,
const char* b)
1898 char *end_a = NULL, *end_b = NULL;
1900 uint64_t na = strtoull(a, &end_a, 10);
1901 uint64_t nb = strtoull(b, &end_b, 10);
1905 return na < nb ? -1 : 1;
1906 cmp = g_utf8_collate(end_a, end_b);
1910 cmp = g_utf8_collate(a, b);
1912 return cmp < 0 ? -1 : cmp > 0 ? 1 : 0;
1917 const Transaction *tb,
const char *actnb)
1919 const char *da, *db;
1922 if ( ta && !tb )
return -1;
1923 if ( !ta && tb )
return +1;
1924 if ( !ta && !tb )
return 0;
1926 if (ta->date_posted != tb->date_posted)
1927 return (ta->date_posted > tb->date_posted) - (ta->date_posted < tb->date_posted);
1933 if (ta_is_closing != tb_is_closing)
1934 return (ta_is_closing - tb_is_closing);
1940 retval = order_by_int64_or_string (actna, actnb);
1944 retval = order_by_int64_or_string (ta->num, tb->num);
1949 if (ta->date_entered != tb->date_entered)
1950 return (ta->date_entered > tb->date_entered) - (ta->date_entered < tb->date_entered);
1953 da = ta->description ? ta->description :
"";
1954 db = tb->description ? tb->description :
"";
1955 retval = g_utf8_collate (da, db);
1967 xaccTransSetDateInternal(Transaction *trans,
time64 *dadate,
time64 val)
1976 PINFO (
"addr=%p set date to %" G_GUINT64_FORMAT
".%09ld %s\n",
1977 trans, val.tv_sec, val.tv_nsec, tstr ? tstr :
"(null)");
1982 qof_instance_set_dirty(QOF_INSTANCE(trans));
1996 set_gains_date_dirty (Transaction *trans)
1998 FOR_EACH_SPLIT(trans, s->gains |= GAINS_STATUS_DATE_DIRTY);
2005 xaccTransSetDateInternal(trans, &trans->date_posted, secs);
2006 set_gains_date_dirty(trans);
2020 GValue v = G_VALUE_INIT;
2026 g_value_init (&v, G_TYPE_DATE);
2027 g_value_set_static_boxed (&v, &date);
2031 xaccTransSetDateInternal(trans, &trans->date_posted,
2033 set_gains_date_dirty (trans);
2040 xaccTransSetDateInternal(trans, &trans->date_entered, secs);
2048 date = g_date_new_dmy(day, mon, year);
2049 if (!g_date_valid(date))
2051 PWARN(
"Attempted to set invalid date %d-%d-%d; set today's date instead.",
2063 GValue v = G_VALUE_INIT;
2065 g_value_init (&v, GNC_TYPE_TIME64);
2066 g_value_set_static_boxed (&v, &time);
2069 qof_instance_set_dirty(QOF_INSTANCE(trans));
2077 char s[2] = {type,
'\0'};
2078 GValue v = G_VALUE_INIT;
2079 g_return_if_fail(trans);
2080 g_value_init (&v, G_TYPE_STRING);
2082 if (!g_strcmp0 (s, g_value_get_string (&v)))
2087 g_value_set_static_string (&v, s);
2090 qof_instance_set_dirty(QOF_INSTANCE(trans));
2095 void xaccTransClearReadOnly (Transaction *trans)
2101 qof_instance_set_dirty(QOF_INSTANCE(trans));
2109 if (trans && reason)
2111 GValue v = G_VALUE_INIT;
2112 g_value_init (&v, G_TYPE_STRING);
2113 g_value_set_static_string (&v, reason);
2116 qof_instance_set_dirty(QOF_INSTANCE(trans));
2128 qofTransSetNum (Transaction *trans,
const char *xnum)
2138 if (!trans || !xnum)
return;
2141 CACHE_REPLACE(trans->num, xnum);
2142 qof_instance_set_dirty(QOF_INSTANCE(trans));
2148 qofTransSetDescription (Transaction *trans,
const char *desc)
2158 if (!trans || !desc)
return;
2161 CACHE_REPLACE(trans->description, desc);
2162 qof_instance_set_dirty(QOF_INSTANCE(trans));
2169 if (!trans || !doclink)
return;
2172 if (doclink[0] ==
'\0')
2178 GValue v = G_VALUE_INIT;
2179 g_value_init (&v, G_TYPE_STRING);
2180 g_value_set_static_string (&v, doclink);
2184 qof_instance_set_dirty(QOF_INSTANCE(trans));
2189 qofTransSetNotes (Transaction *trans,
const char *notes)
2199 GValue v = G_VALUE_INIT;
2200 if (!trans || !notes)
return;
2201 g_value_init (&v, G_TYPE_STRING);
2202 g_value_set_static_string (&v, notes);
2205 qof_instance_set_dirty(QOF_INSTANCE(trans));
2218 GValue v = G_VALUE_INIT;
2219 g_value_init (&v, G_TYPE_INT64);
2220 g_value_set_int64 (&v, 1);
2228 qof_instance_set_dirty(QOF_INSTANCE(trans));
2240 g_list_free (trans->splits);
2241 trans->splits = NULL;
2249 if (!trans || i < 0)
return NULL;
2251 FOR_EACH_SPLIT(trans, {
if (i == j)
return s; j++; });
2259 g_return_val_if_fail(trans && split, -1);
2261 FOR_EACH_SPLIT(trans, {
if (s == split)
return j; j++; });
2268 return trans ? trans->splits : NULL;
2274 GList *pay_splits = NULL;
2275 FOR_EACH_SPLIT (trans,
2278 pay_splits = g_list_prepend (pay_splits, s);
2281 pay_splits = g_list_reverse (pay_splits);
2288 GList *apar_splits = NULL;
2289 if (!trans)
return NULL;
2291 FOR_EACH_SPLIT (trans,
2297 apar_splits = g_list_prepend (apar_splits, s);
2305 apar_splits = g_list_prepend (apar_splits, s);
2310 apar_splits = g_list_reverse (apar_splits);
2316 FOR_EACH_SPLIT (trans,
2327 FOR_EACH_SPLIT (trans,
2352 g_return_val_if_fail (trans != NULL, 0);
2353 FOR_EACH_SPLIT(trans, i++);
2360 return trans ? trans->num : NULL;
2366 return trans ? trans->description : NULL;
2372 g_return_val_if_fail (trans, NULL);
2374 GValue v = G_VALUE_INIT;
2376 const char* doclink = G_VALUE_HOLDS_STRING (&v) ? g_value_get_string (&v) : NULL;
2385 g_return_val_if_fail (trans, NULL);
2387 GValue v = G_VALUE_INIT;
2389 const char *notes = G_VALUE_HOLDS_STRING (&v) ? g_value_get_string (&v) : NULL;
2398 if (!trans)
return FALSE;
2400 GValue v = G_VALUE_INIT;
2403 if (G_VALUE_HOLDS_INT64 (&v))
2404 rv = (g_value_get_int64 (&v) ? 1 : 0);
2418 return trans ? trans->date_posted : 0;
2425 return trans ? trans->date_entered : 0;
2432 return trans ? trans->date_posted : 0;
2439 g_date_clear (&result, 1);
2445 GValue v = G_VALUE_INIT;
2447 if (G_VALUE_HOLDS_BOXED (&v))
2448 result = *(GDate*)g_value_get_boxed (&v);
2450 if (! g_date_valid (&result) ||
gdate_to_time64 (result) == INT64_MAX)
2460 g_date_set_dmy(&result, stm->tm_mday,
2461 (GDateMonth)(stm->tm_mon + 1),
2462 stm->tm_year + 1900);
2473 return trans ? trans->date_entered : 0;
2480 GValue v = G_VALUE_INIT;
2481 if (!trans)
return 0;
2483 if (G_VALUE_HOLDS_BOXED (&v))
2485 ret = ((
Time64*)g_value_get_boxed (&v))->t;
2496 gboolean has_nonAPAR_split = FALSE;
2500 if (trans->txn_type != TXN_TYPE_UNCACHED)
2501 return trans->txn_type;
2512 has_nonAPAR_split = TRUE;
2519 if (invoice && trans == gncInvoiceGetPostedTxn (invoice))
2529 return trans->txn_type;
2538 GValue v = G_VALUE_INIT;
2540 const char *readonly_reason = G_VALUE_HOLDS_STRING (&v) ?
2541 g_value_get_string (&v) : NULL;
2543 return readonly_reason;
2547 xaccTransIsSXTemplate (
const Transaction * trans)
2552 char* formula = NULL;
2553 g_object_get (split0,
"sx-debit-formula", &formula, NULL);
2554 if (formula != NULL)
2559 g_object_get (split0,
"sx-credit-formula", &formula, NULL);
2560 if (formula != NULL)
2571 GDate *threshold_date;
2582 if (xaccTransIsSXTemplate (trans))
2586 g_assert(threshold_date);
2594 if (g_date_compare(&trans_date, threshold_date) < 0)
2603 g_date_free(threshold_date);
2617 if (trans->date_posted > present)
2635 Split *split = node->data;
2637 if (!xaccTransStillHasSplit(trans, split))
2672 Split *split = node->data;
2674 if (!xaccTransStillHasSplit(trans, split))
2679 if (split->reconciled == state)
2700 counter_thunk(Transaction *t,
void *data)
2702 (*((guint*)data))++;
2711 counter_thunk, (
void*)&count);
2721 GValue v = G_VALUE_INIT;
2722 char iso8601_str[ISO_DATELENGTH + 1] =
"";
2724 g_return_if_fail(trans && reason);
2731 PWARN (
"Refusing to void a read-only transaction!");
2736 if (G_VALUE_HOLDS_STRING (&v))
2739 g_value_init (&v, G_TYPE_STRING);
2741 g_value_set_static_string (&v, _(
"Voided transaction"));
2743 g_value_set_static_string (&v, reason);
2747 g_value_set_static_string (&v, iso8601_str);
2751 FOR_EACH_SPLIT(trans, xaccSplitVoid(s));
2768 g_return_val_if_fail (trans, NULL);
2770 GValue v = G_VALUE_INIT;
2772 const char *void_reason = G_VALUE_HOLDS_STRING (&v) ? g_value_get_string (&v) : NULL;
2781 GValue v = G_VALUE_INIT;
2782 const char *s = NULL;
2785 g_return_val_if_fail(tr, void_time);
2787 if (G_VALUE_HOLDS_STRING (&v))
2789 s = g_value_get_string (&v);
2800 GValue v = G_VALUE_INIT;
2801 const char *s = NULL;
2802 g_return_if_fail(trans);
2805 if (s == NULL)
return;
2809 if (G_VALUE_HOLDS_STRING (&v))
2816 FOR_EACH_SPLIT(trans, xaccSplitUnvoid(s));
2819 xaccTransClearReadOnly(trans);
2827 GValue v = G_VALUE_INIT;
2828 g_return_val_if_fail(orig, NULL);
2834 qof_instance_set_dirty (QOF_INSTANCE (orig));
2838 g_return_val_if_fail (trans, NULL);
2842 FOR_EACH_SPLIT(trans,
2850 g_value_init (&v, GNC_TYPE_GUID);
2856 xaccTransClearReadOnly(trans);
2858 qof_instance_set_dirty(QOF_INSTANCE(trans));
2866 GValue v = G_VALUE_INIT;
2867 Transaction *retval = NULL;
2868 g_return_val_if_fail(trans, NULL);
2870 if (G_VALUE_HOLDS_BOXED (&v))
2872 GncGUID* guid = g_value_get_boxed (&v);
2893 xaccTransScrubGainsDate (Transaction *trans)
2896 SplitList *splits_copy = g_list_copy(trans->splits);
2897 for (node = splits_copy; node; node = node->next)
2899 Split *s = node->data;
2901 if (!xaccTransStillHasSplit(trans, s))
continue;
2902 xaccSplitDetermineGainStatus(s);
2904 if ((GAINS_STATUS_GAINS & s->gains) &&
2906 ((s->gains_split->gains & GAINS_STATUS_DATE_DIRTY) ||
2907 (s->gains & GAINS_STATUS_DATE_DIRTY)))
2909 Transaction *source_trans = s->gains_split->parent;
2910 s->gains &= ~GAINS_STATUS_DATE_DIRTY;
2911 s->gains_split->gains &= ~GAINS_STATUS_DATE_DIRTY;
2913 FOR_EACH_SPLIT(trans, s->gains &= ~GAINS_STATUS_DATE_DIRTY);
2916 g_list_free(splits_copy);
2926 ENTER(
"(trans=%p)", trans);
2929 xaccTransScrubGainsDate(trans);
2933 for (node = trans->splits; node; node = node->next)
2935 Split *s = node->data;
2937 if (!xaccTransStillHasSplit(trans, s))
continue;
2939 xaccSplitDetermineGainStatus(s);
2940 if (s->gains & GAINS_STATUS_ADIRTY)
2942 gboolean altered = FALSE;
2943 s->gains &= ~GAINS_STATUS_ADIRTY;
2948 if (altered)
goto restart;
2953 FOR_EACH_SPLIT(trans,
2954 if ((s->gains & GAINS_STATUS_VDIRTY) ||
2956 (s->gains_split->gains & GAINS_STATUS_VDIRTY)))
2960 LEAVE(
"(trans=%p)", trans);
2964 xaccTransFindSplitByAccount(
const Transaction *trans,
const Account *acc)
2966 if (!trans || !acc)
return NULL;
2972 record_price (Split *split,
2978 GNCPriceDB* pricedb;
2979 gnc_commodity* comm;
2980 gnc_commodity* curr;
2982 gnc_numeric price_value, value, amount;
3014 PriceSource oldsource = gnc_price_get_source (price);
3015 price_value = gnc_price_get_value (price);
3022 if (oldsource < source &&
3023 !(oldsource == PRICE_SOURCE_XFER_DLG_VAL &&
3024 source == PRICE_SOURCE_SPLIT_REG))
3037 gnc_price_begin_edit (price);
3038 gnc_price_set_time64 (price, time);
3039 gnc_price_set_source (price, source);
3040 gnc_price_set_typestr (price, PRICE_TYPE_TRN);
3041 gnc_price_set_value (price, value);
3042 gnc_price_commit_edit (price);
3050 gnc_price_begin_edit (price);
3051 gnc_price_set_commodity (price, comm);
3052 gnc_price_set_currency (price, curr);
3053 gnc_price_set_time64 (price, time);
3054 gnc_price_set_source (price, source);
3055 gnc_price_set_typestr (price, PRICE_TYPE_TRN);
3056 gnc_price_set_value (price, value);
3058 gnc_price_commit_edit (price);
3066 record_price (n->data, source);
3074 destroy_tx_on_book_close(
QofInstance *ent, gpointer data)
3076 Transaction* tx = GNC_TRANSACTION(ent);
3086 gnc_transaction_book_end(QofBook* book)
3103 static QofObject trans_object_def =
3106 DI(.e_type = ) GNC_ID_TRANS,
3107 DI(.type_label = ) "Transaction",
3109 DI(.book_begin = ) NULL,
3110 DI(.book_end = ) gnc_transaction_book_end,
3119 trans_is_balanced_p (const Transaction *trans)
3124 gboolean xaccTransRegister (
void)
3126 static QofParam params[] =
3129 TRANS_NUM, QOF_TYPE_STRING,
3135 TRANS_DESCRIPTION, QOF_TYPE_STRING,
3140 TRANS_DATE_ENTERED, QOF_TYPE_DATE,
3145 TRANS_DATE_POSTED, QOF_TYPE_DATE,
3150 TRANS_DATE_DUE, QOF_TYPE_DATE,
3154 TRANS_IMBALANCE, QOF_TYPE_NUMERIC,
3158 TRANS_NOTES, QOF_TYPE_STRING,
3163 TRANS_DOCLINK, QOF_TYPE_STRING,
3168 TRANS_IS_CLOSING, QOF_TYPE_BOOLEAN,
3172 TRANS_IS_BALANCED, QOF_TYPE_BOOLEAN,
3176 TRANS_TYPE, QOF_TYPE_CHAR,
3181 TRANS_VOID_STATUS, QOF_TYPE_BOOLEAN,
3185 TRANS_VOID_REASON, QOF_TYPE_STRING,
3189 TRANS_VOID_TIME, QOF_TYPE_DATE,
3193 TRANS_SPLITLIST, GNC_ID_SPLIT,
3201 QOF_PARAM_GUID, QOF_TYPE_GUID,
3213 _utest_trans_fill_functions (
void)
3217 func->mark_trans = mark_trans;
3218 func->gen_event_trans = gen_event_trans;
3219 func->xaccFreeTransaction = xaccFreeTransaction;
3220 func->destroy_gains = destroy_gains;
3221 func->do_destroy = do_destroy;
3222 func->was_trans_emptied = was_trans_emptied;
3223 func->trans_on_error = trans_on_error;
3224 func->trans_cleanup_commit = trans_cleanup_commit;
3225 func->xaccTransScrubGainsDate = xaccTransScrubGainsDate;
3226 func->dupe_trans = dupe_trans;
void xaccSplitSetValue(Split *split, gnc_numeric val)
The xaccSplitSetValue() method sets the value of this split in the transaction's commodity.
GNCPrice * gnc_pricedb_lookup_day_t64(GNCPriceDB *db, const gnc_commodity *c, const gnc_commodity *currency, time64 t)
Return the price between the two commodities on the indicated day.
time64 gnc_iso8601_to_time64_gmt(const gchar *)
The gnc_iso8601_to_time64_gmt() routine converts an ISO-8601 style date/time string to time64...
int qof_instance_version_cmp(const QofInstance *left, const QofInstance *right)
Compare two instances, based on their last update times.
Never round at all, and signal an error if there is a fractional result in a computation.
commit of object update failed because another user has deleted the object
GNCPrice * gnc_price_create(QofBook *book)
gnc_price_create - returns a newly allocated and initialized price with a reference count of 1...
int xaccAccountTreeForEachTransaction(Account *acc, TransactionCallback proc, void *data)
Traverse all of the transactions in the given account group.
gint xaccSplitOrder(const Split *sa, const Split *sb)
The xaccSplitOrder(sa,sb) method is useful for sorting.
High-Level API for imposing Lot constraints.
gboolean xaccTransHasReconciledSplits(const Transaction *trans)
FIXME: document me.
Transaction * xaccMallocTransaction(QofBook *book)
The xaccMallocTransaction() will malloc memory and initialize it.
gboolean gnc_numeric_equal(gnc_numeric a, gnc_numeric b)
Equivalence predicate: Returns TRUE (1) if a and b represent the same number.
void xaccTransSetDatePostedSecsNormalized(Transaction *trans, time64 time)
This function sets the posted date of the transaction, specified by a time64 (see ctime(3))...
gchar * gnc_num_dbg_to_string(gnc_numeric n)
Convert to string.
int gnc_commodity_get_fraction(const gnc_commodity *cm)
Retrieve the fraction for the specified commodity.
void xaccTransClearSplits(Transaction *trans)
Remove all splits from the transaction.
Business Interface: Object OWNERs.
gboolean xaccTransHasSplitsInStateByAccount(const Transaction *trans, const char state, const Account *account)
FIXME: document me.
Split * xaccTransGetSplit(const Transaction *trans, int i)
Return a pointer to the indexed split in this transaction's split list.
time64 xaccTransGetDate(const Transaction *trans)
Retrieve the posted date of the transaction.
void qof_instance_set_kvp(QofInstance *, GValue const *value, unsigned count,...)
Sets a KVP slot to a value from a GValue.
gboolean xaccTransUseTradingAccounts(const Transaction *trans)
Determine whether this transaction should use commodity trading accounts.
void qof_instance_set_guid(gpointer ptr, const GncGUID *guid)
Set the GncGUID of this instance.
gboolean xaccTransIsReadonlyByPostedDate(const Transaction *trans)
Returns TRUE if this Transaction is read-only because its posted-date is older than the "auto-readonl...
Date and Time handling routines.
#define qof_instance_is_dirty
Return value of is_dirty flag.
QofBook * qof_instance_get_book(gconstpointer inst)
Return the book pointer.
gboolean xaccAccountIsPriced(const Account *acc)
Returns true if the account is a stock, mutual fund or currency, otherwise false. ...
gboolean qof_collection_is_dirty(const QofCollection *col)
Return value of 'dirty' flag on collection.
gboolean xaccTransIsOpen(const Transaction *trans)
The xaccTransIsOpen() method returns TRUE if the transaction is open for editing. ...
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...
char xaccTransGetTxnType(Transaction *trans)
Returns the Transaction Type: note this type will be derived from the transaction splits...
QofInstance * qof_collection_lookup_entity(const QofCollection *col, const GncGUID *guid)
Find the entity going only from its guid.
#define TXN_TYPE_INVOICE
Transaction is an invoice.
#define PINFO(format, args...)
Print an informational note.
GNCAccountType xaccAccountGetType(const Account *acc)
Returns the account's account type.
gboolean xaccSplitDestroy(Split *split)
Destructor.
QofBackendError
The errors that can be reported to the GUI & other front-end users.
int xaccAccountGetCommoditySCU(const Account *acc)
Return the SCU for the account.
gnc_numeric gnc_numeric_neg(gnc_numeric a)
Returns a newly created gnc_numeric that is the negative of the given gnc_numeric value...
void xaccTransSetNotes(Transaction *trans, const char *notes)
Sets the transaction Notes.
const char * xaccTransGetVoidReason(const Transaction *trans)
Returns the user supplied textual reason why a transaction was voided.
void xaccTransWriteLog(Transaction *trans, char flag)
void gnc_price_unref(GNCPrice *p)
gnc_price_unref - indicate you're finished with a price (i.e.
void qof_backend_set_error(QofBackend *qof_be, QofBackendError err)
Set the error on the specified QofBackend.
const char * xaccTransGetReadOnly(Transaction *trans)
Returns a non-NULL value if this Transaction was marked as read-only with some specific "reason" text...
gboolean qof_instance_get_destroying(gconstpointer ptr)
Retrieve the flag that indicates whether or not this object is about to be destroyed.
void xaccSplitCopyOnto(const Split *from_split, Split *to_split)
This is really a helper for xaccTransCopyOnto.
gboolean gnc_pricedb_add_price(GNCPriceDB *db, GNCPrice *p)
Add a price to the pricedb.
void qof_instance_set(QofInstance *inst, const gchar *first_prop,...)
Wrapper for g_object_set Group setting multiple parameters in a single begin/commit/rollback.
commit of object update failed because another user has modified the object
void qof_class_register(QofIdTypeConst obj_name, QofSortFunc default_sort_function, const QofParam *params)
This function registers a new object class with the Qof subsystem.
char xaccSplitGetReconcile(const Split *split)
Returns the value of the reconcile flag.
gboolean gnc_commodity_equal(const gnc_commodity *a, const gnc_commodity *b)
This routine returns TRUE if the two commodities are equal.
void xaccSplitComputeCapGains(Split *split, Account *gain_acc)
The xaccSplitComputeCapGains() routine computes the cap gains or losses for the indicated split...
void xaccTransSetDescription(Transaction *trans, const char *desc)
Sets the transaction Description.
gnc_numeric gnc_numeric_add(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Return a+b.
void xaccTransSetNum(Transaction *trans, const char *xnum)
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.
void xaccTransRecordPrice(Transaction *trans, PriceSource source)
The xaccTransRecordPrice() method iterates through the splits and and record the non-currency equival...
gboolean gnc_numeric_zero_p(gnc_numeric a)
Returns 1 if the given gnc_numeric is 0 (zero), else returns 0.
void xaccTransCopyOnto(const Transaction *from_trans, Transaction *to_trans)
Copy a transaction to another using the function below without changing any account information...
void xaccSplitSetReconcile(Split *split, char recn)
Set the reconcile flag.
Transaction * xaccSplitGetParent(const Split *split)
Returns the parent transaction of the split.
gchar * guid_to_string_buff(const GncGUID *guid, gchar *str)
The guid_to_string_buff() routine puts a null-terminated string encoding of the id into the memory po...
Use any denominator which gives an exactly correct ratio of numerator to denominator.
int(* QofSortFunc)(gconstpointer, gconstpointer)
This function is the default sort function for a particular object type.
gboolean xaccTransIsBalanced(const Transaction *trans)
Returns true if the transaction is balanced according to the rules currently in effect.
#define QOF_OBJECT_VERSION
Defines the version of the core object object registration interface.
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.
gboolean qof_commit_edit(QofInstance *inst)
commit_edit helpers
#define PERR(format, args...)
Log a serious error.
gboolean gncBusinessIsPaymentAcctType(GNCAccountType type)
Returns whether the given account type is a valid type to use in business payments.
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.
#define ENTER(format, args...)
Print a function entry debugging message.
gnc_numeric xaccSplitGetBalance(const Split *s)
Returns the running balance up to and including the indicated split.
Split * xaccTransGetFirstPaymentAcctSplit(const Transaction *trans)
The xaccTransGetFirstPaymentAcctSplit() method returns a pointer to the first split in this transacti...
#define QOF_PARAM_BOOK
"Known" Object Parameters – all objects must support these
QofBackendError qof_backend_get_error(QofBackend *qof_be)
Get the last backend error.
void xaccTransSetDatePostedGDate(Transaction *trans, GDate date)
This method modifies posted date of the transaction, specified by a GDate.
void qof_collection_foreach(const QofCollection *col, QofInstanceForeachCB cb_func, gpointer user_data)
Call the callback for each entity in the collection.
void(* QofSetterFunc)(gpointer, gpointer)
The QofSetterFunc defines an function pointer for parameter setters.
GNCPriceDB * gnc_pricedb_get_db(QofBook *book)
Return the pricedb associated with the book.
void qof_instance_get_kvp(QofInstance *, GValue *value, unsigned count,...)
Retrieves the contents of a KVP slot into a provided GValue.
const char * xaccTransGetDocLink(const Transaction *trans)
Gets the transaction Document Link.
gboolean gnc_numeric_negative_p(gnc_numeric a)
Returns 1 if a < 0, otherwise returns 0.
gboolean xaccTransHasReconciledSplitsByAccount(const Transaction *trans, const Account *account)
FIXME: document me.
void xaccTransSetCurrency(Transaction *trans, gnc_commodity *curr)
Set a new currency on a transaction.
Account used to record multiple commodity transactions.
void xaccTransDestroy(Transaction *trans)
Destroys a transaction.
gboolean xaccSplitEqual(const Split *sa, const Split *sb, gboolean check_guids, gboolean check_balances, gboolean check_txn_splits)
Equality.
#define PWARN(format, args...)
Log a warning.
const char * xaccTransGetNotes(const Transaction *trans)
Gets the transaction Notes.
Transaction * xaccTransLookup(const GncGUID *guid, QofBook *book)
The xaccTransLookup() subroutine will return the transaction associated with the given id...
void xaccTransSetIsClosingTxn(Transaction *trans, gboolean is_closing)
Sets whether or not this transaction is a "closing transaction".
void qof_instance_init_data(QofInstance *inst, QofIdType type, QofBook *book)
Initialise the settings associated with an instance.
MonetaryList * gnc_monetary_list_delete_zeros(MonetaryList *list)
Delete all entries in the list that have zero value.
gboolean qof_begin_edit(QofInstance *inst)
begin_edit
int xaccTransCountSplits(const Transaction *trans)
Returns the number of splits in this transaction.
void xaccTransSetTxnType(Transaction *trans, char type)
Set the Transaction Type: note the type will be saved into the Transaction kvp property as a backward...
#define TXN_TYPE_NONE
No transaction type.
convert single-entry accounts to clean double-entry
gnc_numeric gnc_numeric_invert(gnc_numeric num)
Invert a gnc_numeric.
GList SplitList
GList of Split.
GDate * qof_book_get_autoreadonly_gdate(const QofBook *book)
Returns the GDate that is the threshold for auto-read-only.
gboolean xaccTransHasSplitsInState(const Transaction *trans, const char state)
FIXME: document me.
guint32 qof_instance_get_idata(gconstpointer inst)
get the instance tag number used for kvp management in sql backends.
void xaccSplitSetAmount(Split *split, gnc_numeric amt)
The xaccSplitSetAmount() method sets the amount in the account's commodity that the split should have...
gboolean xaccTransEqual(const Transaction *ta, const Transaction *tb, gboolean check_guids, gboolean check_splits, gboolean check_balances, gboolean assume_ordered)
Equality.
gnc_numeric gnc_numeric_convert(gnc_numeric n, gint64 denom, gint how)
Change the denominator of a gnc_numeric value to the specified denominator under standard arguments '...
Reduce the result value by common factor elimination, using the smallest possible value for the denom...
gnc_numeric xaccTransGetImbalanceValue(const Transaction *trans)
The xaccTransGetImbalanceValue() method returns the total value of the transaction.
void xaccTransSetReadOnly(Transaction *trans, const char *reason)
Set the transaction to be ReadOnly by setting a non-NULL value as "reason".
void xaccTransVoid(Transaction *trans, const char *reason)
xaccTransVoid voids a transaction.
Transaction * xaccTransClone(const Transaction *from)
The xaccTransClone() method will create a complete copy of an existing transaction.
#define YREC
The Split has been reconciled.
#define GUID_ENCODING_LENGTH
Number of characters needed to encode a guid as a string not including the null terminator.
#define FREC
frozen into accounting period
gnc_numeric gnc_numeric_error(GNCNumericErrorCode error_code)
Create a gnc_numeric object that signals the error condition noted by error_code, rather than a numbe...
void gnc_monetary_list_free(MonetaryList *list)
Free a MonetaryList and all the monetaries it points to.
void xaccTransScrubImbalance(Transaction *trans, Account *root, Account *account)
Correct transaction imbalances.
void qof_instance_copy_book(gpointer ptr1, gconstpointer ptr2)
Copy the book from one QofInstances to another.
time64 xaccTransRetDatePosted(const Transaction *trans)
Retrieve the posted date of the transaction.
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.
void xaccTransScrubGains(Transaction *trans, Account *gain_acc)
The xaccTransScrubGains() routine performs a number of cleanup functions on the indicated transaction...
Transaction * xaccTransCloneNoKvp(const Transaction *from)
The xaccTransCloneNoKvp() method will create a complete copy of an existing transaction except that ...
gboolean xaccTransInFutureByPostedDate(const Transaction *trans)
Returns TRUE if this Transaction's posted-date is in the future.
const char * xaccTransGetDescription(const Transaction *trans)
Gets the transaction Description.
Argument is not a valid number.
– Business Helper Functions
time64 gdate_to_time64(GDate d)
Turns a GDate into a time64, returning the first second of the day.
gboolean qof_commit_edit_part2(QofInstance *inst, void(*on_error)(QofInstance *, QofBackendError), void(*on_done)(QofInstance *), void(*on_free)(QofInstance *))
part2 – deal with the backend
gboolean gncOwnerGetOwnerFromLot(GNCLot *lot, GncOwner *owner)
Get the owner from the lot.
gpointer(* QofAccessFunc)(gpointer object, const QofParam *param)
The QofAccessFunc defines an arbitrary function pointer for access functions.
#define xaccTransGetBook(X)
gboolean xaccAccountIsAPARType(GNCAccountType t)
Convenience function to check if the account is a valid business account type (meaning an Accounts Pa...
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.
#define MAX_DATE_LENGTH
The maximum length of a string created by the date printers.
void qof_collection_mark_clean(QofCollection *)
reset value of dirty flag
void xaccTransSetDateDue(Transaction *trans, time64 time)
Dates and txn-type for A/R and A/P "invoice" postings.
void xaccTransCommitEdit(Transaction *trans)
The xaccTransCommitEdit() method indicates that the changes to the transaction and its splits are com...
Additional event handling code.
gnc_numeric gnc_numeric_div(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Division.
#define xaccSplitGetGUID(X)
#define GNC_INVOICE_ID
STRING CONSTANTS ********************************************** Used to declare constant KVP keys use...
#define TXN_TYPE_LINK
Transaction is a link between (invoice and payment) lots.
void xaccTransBeginEdit(Transaction *trans)
The xaccTransBeginEdit() method must be called before any changes are made to a transaction or any of...
int xaccTransGetSplitIndex(const Transaction *trans, const Split *split)
Inverse of xaccTransGetSplit()
SplitList * xaccTransGetAPARAcctSplitList(const Transaction *trans, gboolean strict)
The xaccTransGetAPARSplitList() method returns a GList of the splits in a transaction that belong to ...
void xaccTransUnvoid(Transaction *trans)
xaccTransUnvoid restores a voided transaction to its original state.
#define TXN_TYPE_PAYMENT
Transaction is a payment.
All type declarations for the whole Gnucash engine.
const GncGUID * qof_entity_get_guid(gconstpointer ent)
time64 xaccTransGetVoidTime(const Transaction *tr)
Returns the time that a transaction was voided.
Split * xaccMallocSplit(QofBook *book)
Constructor.
#define xaccTransGetGUID(X)
time64 xaccTransGetDateEntered(const Transaction *trans)
Retrieve the date of when the transaction was entered.
GncInvoice * gncInvoiceGetInvoiceFromLot(GNCLot *lot)
Given a LOT, find and return the Invoice attached to the lot.
API for the transaction logger.
Business Invoice Interface.
const char * gnc_commodity_get_printname(const gnc_commodity *cm)
Retrieve the 'print' name for the specified commodity.
Transaction * xaccTransReverse(Transaction *orig)
xaccTransReverse creates a Transaction that reverses the given transaction by inverting all the numer...
guint gnc_book_count_transactions(QofBook *book)
void xaccTransSetDatePostedSecs(Transaction *trans, time64 secs)
The xaccTransSetDatePostedSecs() method will modify the posted date of the transaction, specified by a time64 (see ctime(3)).
Split * xaccTransGetFirstAPARAcctSplit(const Transaction *trans, gboolean strict)
The xaccTransGetFirstPaymentAcctSplit() method returns a pointer to the first split in this transacti...
gboolean xaccTransGetVoidStatus(const Transaction *trans)
Retrieve information on whether or not a transaction has been voided.
gboolean qof_book_is_readonly(const QofBook *book)
Return whether the book is read only.
gboolean xaccSplitAssign(Split *split)
The`xaccSplitAssign() routine will take the indicated split and, if it doesn't already belong to a lo...
SplitList * xaccTransGetPaymentAcctSplitList(const Transaction *trans)
The xaccTransGetPaymentAcctSplitList() method returns a GList of the splits in a transaction that bel...
gnc_numeric xaccSplitGetValue(const Split *split)
Returns the value of this split in the transaction's commodity.
void qof_event_suspend(void)
Suspend all engine events.
int qof_string_number_compare_func(gpointer a, gpointer b, gint options, QofParam *getter)
Compare two parameter(strings) as if they are numbers! the two objects, a and b, are the objects bein...
void gnc_gdate_set_time64(GDate *gd, time64 time)
Set a GDate to a time64.
Account * xaccSplitGetAccount(const Split *split)
Returns the account of this split, which was set through xaccAccountInsertSplit().
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Get the account's commodity.
const GncGUID * guid_null(void)
Returns a GncGUID which is guaranteed to never reference any entity.
gboolean xaccTransGetIsClosingTxn(const Transaction *trans)
Returns whether this transaction is a "closing transaction".
gnc_commodity * xaccTransGetCurrency(const Transaction *trans)
Returns the valuation commodity of this transaction.
This is the private header for the account structure.
void qof_event_resume(void)
Resume engine event generation.
gint qof_instance_guid_compare(gconstpointer ptr1, gconstpointer ptr2)
Compare the GncGUID values of two instances.
time64 gnc_time64_get_today_end(void)
The gnc_time64_get_today_end() routine returns a time64 value corresponding to the last second of tod...
MonetaryList * xaccTransGetImbalance(const Transaction *trans)
The xaccTransGetImbalance method returns a list giving the value of the transaction in each currency ...
void xaccTransSetDocLink(Transaction *trans, const char *doclink)
Sets the transaction Document Link.
PriceSource
Price source enum.
Transaction * xaccTransGetReversedBy(const Transaction *trans)
Returns the transaction that reversed the given transaction.
#define LEAVE(format, args...)
Print a function exit debugging message.
gboolean xaccScrubLot(GNCLot *lot)
The xaccScrubLot() routine makes sure that the indicated lot is self-consistent and properly balanced...
struct tm * gnc_gmtime(const time64 *secs)
fill out a time struct from a 64-bit time value
const char * gnc_commodity_get_unique_name(const gnc_commodity *cm)
Retrieve the 'unique' name for the specified commodity.
Round to the nearest integer, rounding away from zero when there are two equidistant nearest integers...
void xaccSplitSetSharePrice(Split *s, gnc_numeric price)
time64 gnc_time(time64 *tbuf)
get the current time
int xaccTransOrder(const Transaction *ta, const Transaction *tb)
The xaccTransOrder(ta,tb) method is useful for sorting.
QofCollection * qof_book_get_collection(const QofBook *book, QofIdType entity_type)
Return The table of entities of the given type.
gint64 time64
Most systems that are currently maintained, including Microsoft Windows, BSD-derived Unixes and Linux...
gboolean qof_object_register(const QofObject *object)
Register new types of object objects.
char * gnc_ctime(const time64 *secs)
Return a string representation of a date from a 64-bit time value.
void xaccTransSetDateEnteredSecs(Transaction *trans, time64 secs)
Modify the date of when the transaction was entered.
time64 xaccTransRetDateEntered(const Transaction *trans)
Retrieve the date of when the transaction was entered.
gboolean qof_book_uses_autoreadonly(const QofBook *book)
Returns TRUE if the auto-read-only feature should be used, otherwise FALSE.
QofBackend * qof_book_get_backend(const QofBook *book)
Retrieve the backend used by this book.
gboolean qof_book_shutting_down(const QofBook *book)
Is the book shutting down?
void qof_event_gen(QofInstance *entity, QofEventId event_id, gpointer event_data)
Invoke all registered event handlers using the given arguments.
void xaccTransSortSplits(Transaction *trans)
Sorts the splits in a transaction, putting the debits first, followed by the credits.
Scheduled Transactions public handling routines.
GDate xaccTransGetDatePostedGDate(const Transaction *trans)
Retrieve the posted date of the transaction.
#define GNC_DENOM_AUTO
Values that can be passed as the 'denom' argument.
The type used to store guids in C.
gboolean qof_book_use_trading_accounts(const QofBook *book)
Returns flag indicating whether this book uses trading accounts.
char * gnc_time64_to_iso8601_buff(time64 time, char *buff)
The gnc_time64_to_iso8601_buff() routine takes the input UTC time64 value and prints it as an ISO-860...
Utilities to Automatically Compute Capital Gains/Losses.
time64 xaccTransRetDateDue(const Transaction *trans)
Dates and txn-type for A/R and A/P "invoice" postings.
size_t qof_print_date_buff(char *buff, size_t buflen, time64 secs)
Convenience: calls through to qof_print_date_dmy_buff().
SplitList * xaccTransGetSplitList(const Transaction *trans)
The xaccTransGetSplitList() method returns a GList of the splits in a transaction.
Commodity handling public routines.
void xaccTransRollbackEdit(Transaction *trans)
The xaccTransRollbackEdit() routine rejects all edits made, and sets the transaction back to where it...
Transaction * xaccTransCopyToClipBoard(const Transaction *from_trans)
Copy a transaction to the 'clipboard' transaction using dupe_transaction.
gboolean gnc_commodity_equiv(const gnc_commodity *a, const gnc_commodity *b)
This routine returns TRUE if the two commodities are equivalent.
gnc_numeric xaccTransGetAccountAmount(const Transaction *trans, const Account *acc)
Same as xaccTransGetAccountValue, but uses the Account's commodity.
GNCLot * xaccSplitGetLot(const Split *split)
Returns the pointer to the debited/credited Lot where this split belongs to, or NULL if it doesn't be...
gnc_numeric xaccTransGetAccountValue(const Transaction *trans, const Account *acc)
The xaccTransGetAccountValue() method returns the total value applied to a particular account...
#define NREC
not reconciled or cleared
gnc_numeric xaccSplitGetAmount(const Split *split)
Returns the amount of the split in the account's commodity.
GDate * gnc_g_date_new_today()
Returns a newly allocated date of the current clock time, taken from time(2).