29 #include <glib/gi18n.h>
36 #include "TransactionP.h"
41 #include "qofinstance-p.h"
46 static gchar account_separator[8] =
".";
47 static gunichar account_uc_separator =
':';
49 static const char *KEY_ASSOC_INCOME_ACCOUNT =
"ofx/associated-income-account";
51 #define AB_ACCOUNT_ID "account-id"
52 #define AB_ACCOUNT_UID "account-uid"
53 #define AB_BANK_CODE "bank-code"
54 #define AB_TRANS_RETRIEVAL "trans-retrieval"
77 PROP_END_CLEARED_BALANCE,
78 PROP_END_RECONCILED_BALANCE,
92 PROP_OFX_INCOME_ACCOUNT,
96 PROP_AB_TRANS_RETRIEVAL,
104 PROP_START_CLEARED_BALANCE,
105 PROP_START_RECONCILED_BALANCE,
108 #define GET_PRIVATE(o) \
109 (G_TYPE_INSTANCE_GET_PRIVATE ((o), GNC_TYPE_ACCOUNT, AccountPrivate))
118 static void xaccAccountBringUpToDate (
Account *acc);
131 return account_separator;
135 gnc_get_account_separator (
void)
137 return account_uc_separator;
141 gnc_set_account_separator (
const gchar *separator)
146 uc = g_utf8_get_char_validated(separator, -1);
147 if ((uc == (gunichar) - 2) || (uc == (gunichar) - 1) || g_unichar_isalnum(uc))
149 account_uc_separator =
':';
150 strcpy(account_separator,
":");
154 account_uc_separator = uc;
155 count = g_unichar_to_utf8(uc, account_separator);
156 account_separator[count] =
'\0';
162 gchar *message = NULL;
163 gchar *account_list = NULL;
165 if ( !invalid_account_names )
168 for ( node = invalid_account_names; node; node = g_list_next(node))
171 account_list = node->data;
174 gchar *tmp_list = NULL;
176 tmp_list = g_strconcat (account_list,
"\n", node->data, NULL );
177 g_free ( account_list );
178 account_list = tmp_list;
186 message = g_strdup_printf(
187 _(
"The separator character \"%s\" is used in one or more account names.\n\n"
188 "This will result in unexpected behaviour. "
189 "Either change the account names or choose another separator character.\n\n"
190 "Below you will find the list of invalid account names:\n"
191 "%s"), separator, account_list );
192 g_free ( account_list );
198 Account *root_account = gnc_book_get_root_account(book);
199 GList *accounts, *node;
200 GList *invalid_list = NULL;
202 g_return_val_if_fail (separator != NULL, NULL);
204 if (root_account == NULL)
208 for (node = accounts; node; node = g_list_next(node))
213 if ( g_strstr_len ( acct_name, -1, separator ) )
214 invalid_list = g_list_prepend ( invalid_list, (gpointer) acct_name );
216 g_free ( acct_name );
218 if (accounts != NULL)
220 g_list_free(accounts);
229 G_INLINE_FUNC
void mark_account (
Account *acc);
233 qof_instance_set_dirty(&acc->inst);
240 G_DEFINE_TYPE(
Account, gnc_account, QOF_TYPE_INSTANCE)
247 priv = GET_PRIVATE(acc);
249 priv->children = NULL;
251 priv->accountName = CACHE_INSERT(
"");
252 priv->accountCode = CACHE_INSERT(
"");
253 priv->description = CACHE_INSERT(
"");
262 priv->commodity = NULL;
263 priv->commodity_scu = 0;
264 priv->non_standard_scu = FALSE;
266 priv->balance = gnc_numeric_zero();
267 priv->cleared_balance = gnc_numeric_zero();
268 priv->reconciled_balance = gnc_numeric_zero();
269 priv->starting_balance = gnc_numeric_zero();
270 priv->starting_cleared_balance = gnc_numeric_zero();
271 priv->starting_reconciled_balance = gnc_numeric_zero();
272 priv->balance_dirty = FALSE;
275 priv->sort_dirty = FALSE;
279 gnc_account_dispose (GObject *acctp)
281 G_OBJECT_CLASS(gnc_account_parent_class)->dispose(acctp);
285 gnc_account_finalize(GObject* acctp)
287 G_OBJECT_CLASS(gnc_account_parent_class)->finalize(acctp);
297 gnc_account_get_property (GObject *
object,
307 g_return_if_fail(GNC_IS_ACCOUNT(
object));
309 account = GNC_ACCOUNT(
object);
310 priv = GET_PRIVATE(account);
314 g_value_set_string(value, priv->accountName);
320 g_value_set_string(value, priv->accountCode);
322 case PROP_DESCRIPTION:
323 g_value_set_string(value, priv->description);
333 g_value_set_int(value, priv->type);
336 g_value_take_object(value, priv->commodity);
338 case PROP_COMMODITY_SCU:
339 g_value_set_int(value, priv->commodity_scu);
341 case PROP_NON_STD_SCU:
342 g_value_set_boolean(value, priv->non_standard_scu);
344 case PROP_SORT_DIRTY:
345 g_value_set_boolean(value, priv->sort_dirty);
347 case PROP_BALANCE_DIRTY:
348 g_value_set_boolean(value, priv->balance_dirty);
350 case PROP_START_BALANCE:
351 g_value_set_boxed(value, &priv->starting_balance);
353 case PROP_START_CLEARED_BALANCE:
354 g_value_set_boxed(value, &priv->starting_cleared_balance);
356 case PROP_START_RECONCILED_BALANCE:
357 g_value_set_boxed(value, &priv->starting_reconciled_balance);
359 case PROP_END_BALANCE:
360 g_value_set_boxed(value, &priv->balance);
362 case PROP_END_CLEARED_BALANCE:
363 g_value_set_boxed(value, &priv->cleared_balance);
365 case PROP_END_RECONCILED_BALANCE:
366 g_value_set_boxed(value, &priv->reconciled_balance);
370 g_value_set_pointer(value, priv->policy);
373 g_value_set_int(value, priv->mark);
375 case PROP_TAX_RELATED:
381 case PROP_TAX_SOURCE:
382 g_value_set_string(value,
385 case PROP_TAX_COPY_NUMBER:
386 g_value_set_int64(value,
392 case PROP_PLACEHOLDER:
398 case PROP_SORT_ORDER:
401 case PROP_LOT_NEXT_ID:
402 key =
"lot-mgmt/next-id";
404 g_value_set_int64 (value, 0);
405 qof_instance_get_kvp (QOF_INSTANCE (account), key, value);
407 case PROP_ONLINE_ACCOUNT:
409 qof_instance_get_kvp (QOF_INSTANCE (account), key, value);
411 case PROP_OFX_INCOME_ACCOUNT:
412 key = KEY_ASSOC_INCOME_ACCOUNT;
413 qof_instance_get_kvp (QOF_INSTANCE (account), key, value);
415 case PROP_AB_ACCOUNT_ID:
416 key = AB_KEY
"/" AB_ACCOUNT_ID;
417 qof_instance_get_kvp (QOF_INSTANCE (account), key, value);
419 case PROP_AB_ACCOUNT_UID:
420 key = AB_KEY
"/" AB_ACCOUNT_UID;
421 qof_instance_get_kvp (QOF_INSTANCE (account), key, value);
423 case PROP_AB_BANK_CODE:
424 key = AB_KEY
"/" AB_BANK_CODE;
425 qof_instance_get_kvp (QOF_INSTANCE (account), key, value);
427 case PROP_AB_TRANS_RETRIEVAL:
428 key = AB_KEY
"/" AB_TRANS_RETRIEVAL;
429 qof_instance_get_kvp (QOF_INSTANCE (account), key, value);
432 G_OBJECT_WARN_INVALID_PROPERTY_ID(
object, prop_id, pspec);
438 gnc_account_set_property (GObject *
object,
445 const gchar *key = NULL;
447 g_return_if_fail(GNC_IS_ACCOUNT(
object));
449 account = GNC_ACCOUNT(
object);
450 if (prop_id < PROP_RUNTIME_0)
451 g_assert (qof_instance_get_editlevel(account));
461 case PROP_DESCRIPTION:
477 case PROP_COMMODITY_SCU:
480 case PROP_NON_STD_SCU:
483 case PROP_SORT_DIRTY:
486 case PROP_BALANCE_DIRTY:
489 case PROP_START_BALANCE:
490 number = g_value_get_boxed(value);
493 case PROP_START_CLEARED_BALANCE:
494 number = g_value_get_boxed(value);
497 case PROP_START_RECONCILED_BALANCE:
498 number = g_value_get_boxed(value);
507 case PROP_TAX_RELATED:
513 case PROP_TAX_SOURCE:
515 g_value_get_string(value));
517 case PROP_TAX_COPY_NUMBER:
519 g_value_get_int64(value));
524 case PROP_PLACEHOLDER:
530 case PROP_SORT_ORDER:
533 case PROP_LOT_NEXT_ID:
534 key =
"lot-mgmt/next-id";
535 qof_instance_set_kvp (QOF_INSTANCE (account), key, value);
537 case PROP_ONLINE_ACCOUNT:
539 qof_instance_set_kvp (QOF_INSTANCE (account), key, value);
541 case PROP_OFX_INCOME_ACCOUNT:
542 key = KEY_ASSOC_INCOME_ACCOUNT;
543 qof_instance_set_kvp (QOF_INSTANCE (account), key, value);
545 case PROP_AB_ACCOUNT_ID:
546 key = AB_KEY
"/" AB_ACCOUNT_ID;
547 qof_instance_set_kvp (QOF_INSTANCE (account), key, value);
549 case PROP_AB_ACCOUNT_UID:
550 key = AB_KEY
"/" AB_ACCOUNT_UID;
551 qof_instance_set_kvp (QOF_INSTANCE (account), key, value);
553 case PROP_AB_BANK_CODE:
554 key = AB_KEY
"/" AB_BANK_CODE;
555 qof_instance_set_kvp (QOF_INSTANCE (account), key, value);
557 case PROP_AB_TRANS_RETRIEVAL:
558 key = AB_KEY
"/" AB_TRANS_RETRIEVAL;
559 qof_instance_set_kvp (QOF_INSTANCE (account), key, value);
562 G_OBJECT_WARN_INVALID_PROPERTY_ID(
object, prop_id, pspec);
570 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
572 gobject_class->dispose = gnc_account_dispose;
573 gobject_class->finalize = gnc_account_finalize;
574 gobject_class->set_property = gnc_account_set_property;
575 gobject_class->get_property = gnc_account_get_property;
579 g_object_class_install_property
582 g_param_spec_string (
"name",
584 "The accountName is an arbitrary string "
585 "assigned by the user. It is intended to "
586 "a short, 5 to 30 character long string "
587 "that is displayed by the GUI as the "
588 "account mnemonic. Account names may be "
589 "repeated. but no two accounts that share "
590 "a parent may have the same name.",
594 g_object_class_install_property
597 g_param_spec_string (
"fullname",
599 "The name of the account concatenated with "
600 "all its parent account names to indicate "
605 g_object_class_install_property
608 g_param_spec_string (
"code",
610 "The account code is an arbitrary string "
611 "assigned by the user. It is intended to "
612 "be reporting code that is a synonym for "
617 g_object_class_install_property
620 g_param_spec_string (
"description",
621 "Account Description",
622 "The account description is an arbitrary "
623 "string assigned by the user. It is intended "
624 "to be a longer, 1-5 sentence description of "
625 "what this account is all about.",
629 g_object_class_install_property
632 g_param_spec_string (
"color",
634 "The account color is a color string assigned "
635 "by the user. It is intended to highlight the "
636 "account based on the users wishes.",
640 g_object_class_install_property
643 g_param_spec_string (
"notes",
645 "The account notes is an arbitrary provided "
646 "for the user to attach any other text that "
647 "they would like to associate with the account.",
651 g_object_class_install_property
654 g_param_spec_int (
"type",
656 "The account type, picked from the enumerated list "
657 "that includes ACCT_TYPE_BANK, ACCT_TYPE_STOCK, "
658 "ACCT_TYPE_CREDIT, ACCT_TYPE_INCOME, etc.",
664 g_object_class_install_property
667 g_param_spec_object (
"commodity",
669 "The commodity field denotes the kind of "
670 "'stuff' stored in this account, whether "
671 "it is USD, gold, stock, etc.",
675 g_object_class_install_property
678 g_param_spec_int (
"commodity-scu",
680 "The smallest fraction of the commodity that is "
681 "tracked. This number is used as the denominator "
682 "value in 1/x, so a value of 100 says that the "
683 "commodity can be divided into hundreths. E.G."
684 "1 USD can be divided into 100 cents.",
690 g_object_class_install_property
693 g_param_spec_boolean (
"non-std-scu",
695 "TRUE if the account SCU doesn't match "
696 "the commodity SCU. This indicates a case "
697 "where the two were accidentally set to "
698 "mismatched values in older versions of "
703 g_object_class_install_property
706 g_param_spec_boolean(
"sort-dirty",
708 "TRUE if the splits in the account needs to be "
709 "resorted. This flag is set by the accounts "
710 "code for certain internal modifications, or "
711 "when external code calls the engine to say a "
712 "split has been modified in a way that may "
713 "affect the sort order of the account. Note: "
714 "This value can only be set to TRUE.",
718 g_object_class_install_property
721 g_param_spec_boolean(
"balance-dirty",
723 "TRUE if the running balances in the account "
724 "needs to be recalculated. This flag is set "
725 "by the accounts code for certain internal "
726 "modifications, or when external code calls "
727 "the engine to say a split has been modified. "
728 "Note: This value can only be set to TRUE.",
732 g_object_class_install_property
735 g_param_spec_boxed(
"start-balance",
737 "The starting balance for the account. This "
738 "parameter is intended for use with backends that "
739 "do not return the complete list of splits for an "
740 "account, but rather return a partial list. In "
741 "such a case, the backend will typically return "
742 "all of the splits after some certain date, and "
743 "the 'starting balance' will represent the "
744 "summation of the splits up to that date.",
748 g_object_class_install_property
750 PROP_START_CLEARED_BALANCE,
751 g_param_spec_boxed(
"start-cleared-balance",
752 "Starting Cleared Balance",
753 "The starting cleared balance for the account. "
754 "This parameter is intended for use with backends "
755 "that do not return the complete list of splits "
756 "for an account, but rather return a partial "
757 "list. In such a case, the backend will "
758 "typically return all of the splits after "
759 "some certain date, and the 'starting cleared "
760 "balance' will represent the summation of the "
761 "splits up to that date.",
765 g_object_class_install_property
767 PROP_START_RECONCILED_BALANCE,
768 g_param_spec_boxed(
"start-reconciled-balance",
769 "Starting Reconciled Balance",
770 "The starting reconciled balance for the "
771 "account. This parameter is intended for use "
772 "with backends that do not return the complete "
773 "list of splits for an account, but rather return "
774 "a partial list. In such a case, the backend "
775 "will typically return all of the splits after "
776 "some certain date, and the 'starting reconciled "
777 "balance' will represent the summation of the "
778 "splits up to that date.",
782 g_object_class_install_property
785 g_param_spec_boxed(
"end-balance",
786 "Ending Account Balance",
787 "This is the current ending balance for the "
788 "account. It is computed from the sum of the "
789 "starting balance and all splits in the account.",
793 g_object_class_install_property
795 PROP_END_CLEARED_BALANCE,
796 g_param_spec_boxed(
"end-cleared-balance",
797 "Ending Account Cleared Balance",
798 "This is the current ending cleared balance for "
799 "the account. It is computed from the sum of the "
800 "starting balance and all cleared splits in the "
805 g_object_class_install_property
807 PROP_END_RECONCILED_BALANCE,
808 g_param_spec_boxed(
"end-reconciled-balance",
809 "Ending Account Reconciled Balance",
810 "This is the current ending reconciled balance "
811 "for the account. It is computed from the sum of "
812 "the starting balance and all reconciled splits "
817 g_object_class_install_property
820 g_param_spec_pointer (
"policy",
822 "The account lots policy.",
825 g_object_class_install_property
828 g_param_spec_int (
"acct-mark",
836 g_object_class_install_property
839 g_param_spec_boolean (
"tax-related",
841 "Whether the account maps to an entry on an "
842 "income tax document.",
846 g_object_class_install_property
849 g_param_spec_string (
"tax-code",
851 "This is the code for mapping an account to a "
852 "specific entry on a taxable document. In the "
853 "United States it is used to transfer totals "
854 "into tax preparation software.",
858 g_object_class_install_property
861 g_param_spec_string (
"tax-source",
863 "This specifies where exported name comes from.",
867 g_object_class_install_property
869 PROP_TAX_COPY_NUMBER,
870 g_param_spec_int64 (
"tax-copy-number",
872 "This specifies the copy number of the tax "
879 g_object_class_install_property
882 g_param_spec_boolean (
"hidden",
884 "Whether the account should be hidden in the "
889 g_object_class_install_property
892 g_param_spec_boolean (
"placeholder",
894 "Whether the account is a placeholder account which does not "
895 "allow transactions to be created, edited or deleted.",
899 g_object_class_install_property
902 g_param_spec_string (
"filter",
904 "The account filter is a value saved to allow "
905 "filters to be recalled.",
909 g_object_class_install_property
912 g_param_spec_string (
"sort-order",
913 "Account Sort Order",
914 "The account sort order is a value saved to allow "
915 "the sort order to be recalled.",
919 g_object_class_install_property
922 g_param_spec_int64 (
"lot-next-id",
924 "Tracks the next id to use in gnc_lot_make_default.",
930 g_object_class_install_property
933 g_param_spec_string (
"online-id",
935 "The online account which corresponds to this "
936 "account for OFX import",
940 g_object_class_install_property(
942 PROP_OFX_INCOME_ACCOUNT,
943 g_param_spec_boxed(
"ofx-income-account",
944 "Associated income account",
945 "Used by the OFX importer.",
949 g_object_class_install_property
952 g_param_spec_string (
"ab-account-id",
953 "AQBanking Account ID",
954 "The AqBanking account which corresponds to this "
955 "account for AQBanking import",
958 g_object_class_install_property
961 g_param_spec_string (
"ab-bank-code",
962 "AQBanking Bank Code",
963 "The online account which corresponds to this "
964 "account for AQBanking import",
968 g_object_class_install_property
971 g_param_spec_int64 (
"ab-account-uid",
972 "AQBanking Account UID",
973 "Tracks the next id to use in gnc_lot_make_default.",
979 g_object_class_install_property
981 PROP_AB_TRANS_RETRIEVAL,
982 g_param_spec_boxed(
"ab-trans-retrieval",
983 "AQBanking Last Transaction Retrieval",
984 "The time of the last transaction retrieval for this "
994 ENTER (
"book=%p\n", book);
997 LEAVE (
"account=%p\n", acc);
1004 gnc_account_get_book(
const Account *account)
1013 gnc_coll_get_root_account (QofCollection *col)
1015 if (!col)
return NULL;
1020 gnc_coll_set_root_account (QofCollection *col,
Account *root)
1026 old_root = gnc_coll_get_root_account (col);
1027 if (old_root == root)
return;
1032 rpriv = GET_PRIVATE(root);
1040 qof_collection_set_data (col, root);
1050 gnc_book_get_root_account (
QofBook *book)
1055 if (!book)
return NULL;
1057 root = gnc_coll_get_root_account (col);
1069 if (root && gnc_account_get_book(root) != book)
1071 PERR (
"cannot mix and match books freely!");
1076 gnc_coll_set_root_account (col, root);
1087 g_return_val_if_fail (book, NULL);
1089 acc = g_object_new (GNC_TYPE_ACCOUNT, NULL);
1090 xaccInitAccount (acc, book);
1103 rpriv = GET_PRIVATE(root);
1106 CACHE_REPLACE(rpriv->accountName,
"Root Account");
1107 mark_account (root);
1109 gnc_book_set_root_account(book, root);
1119 g_return_val_if_fail(GNC_IS_ACCOUNT(from), NULL);
1120 g_return_val_if_fail(QOF_IS_BOOK(book), NULL);
1123 ret = g_object_new (GNC_TYPE_ACCOUNT, NULL);
1124 g_return_val_if_fail (ret, NULL);
1126 from_priv = GET_PRIVATE(from);
1127 priv = GET_PRIVATE(ret);
1128 xaccInitAccount (ret, book);
1133 priv->type = from_priv->type;
1135 priv->accountName = CACHE_INSERT(from_priv->accountName);
1136 priv->accountCode = CACHE_INSERT(from_priv->accountCode);
1137 priv->description = CACHE_INSERT(from_priv->description);
1147 priv->commodity_scu = from_priv->commodity_scu;
1148 priv->non_standard_scu = from_priv->non_standard_scu;
1150 qof_instance_set_dirty(&ret->inst);
1159 xaccFreeOneChildAccount (
Account *acc, gpointer dummy)
1163 if (qof_instance_get_editlevel(acc) == 0)
1169 xaccFreeAccountChildren (
Account *acc)
1175 priv = GET_PRIVATE(acc);
1176 children = g_list_copy(priv->children);
1177 g_list_foreach(children, (GFunc)xaccFreeOneChildAccount, NULL);
1178 g_list_free(children);
1182 g_list_free(priv->children);
1183 priv->children = NULL;
1191 xaccFreeAccount (
Account *acc)
1196 g_return_if_fail(GNC_IS_ACCOUNT(acc));
1198 priv = GET_PRIVATE(acc);
1203 PERR (
" instead of calling xaccFreeAccount(), please call \n"
1204 " xaccAccountBeginEdit(); xaccAccountDestroy(); \n");
1207 xaccFreeAccountChildren(acc);
1213 PERR (
" instead of calling xaccFreeAccount(), please call \n"
1214 " xaccAccountBeginEdit(); xaccAccountDestroy(); \n");
1216 for (lp = priv->lots; lp; lp = lp->next)
1219 gnc_lot_destroy (lot);
1221 g_list_free (priv->lots);
1232 PERR (
" instead of calling xaccFreeAccount(), please call \n"
1233 " xaccAccountBeginEdit(); xaccAccountDestroy(); \n");
1235 qof_instance_reset_editlevel(acc);
1237 slist = g_list_copy(priv->splits);
1238 for (lp = slist; lp; lp = lp->next)
1250 CACHE_REPLACE(priv->accountName, NULL);
1251 CACHE_REPLACE(priv->accountCode, NULL);
1252 CACHE_REPLACE(priv->description, NULL);
1257 priv->parent = NULL;
1258 priv->children = NULL;
1260 priv->balance = gnc_numeric_zero();
1261 priv->cleared_balance = gnc_numeric_zero();
1262 priv->reconciled_balance = gnc_numeric_zero();
1266 priv->commodity = NULL;
1268 priv->balance_dirty = FALSE;
1269 priv->sort_dirty = FALSE;
1272 g_object_unref(acc);
1282 g_return_if_fail(acc);
1294 PERR(
"commit error: %d", errcode);
1295 gnc_engine_signal_commit_error( errcode );
1303 priv = GET_PRIVATE(acc);
1306 xaccFreeAccount(acc);
1310 destroy_pending_splits_for_account(
QofInstance *ent, gpointer acc)
1316 while ((split = xaccTransFindSplitByAccount(trans, acc)))
1326 g_return_if_fail(acc);
1331 priv = GET_PRIVATE(acc);
1337 qof_instance_increase_editlevel(acc);
1340 xaccFreeAccountChildren(acc);
1342 PINFO (
"freeing splits for account %p (%s)",
1343 acc, priv->accountName ? priv->accountName :
"(null)");
1351 slist = g_list_copy(priv->splits);
1352 for (lp = slist; lp; lp = lp->next)
1354 Split *s = lp->data;
1361 g_list_free(priv->splits);
1362 priv->splits = NULL;
1379 for (lp = priv->lots; lp; lp = lp->next)
1382 gnc_lot_destroy (lot);
1385 g_list_free(priv->lots);
1388 qof_instance_set_dirty(&acc->inst);
1389 qof_instance_decrease_editlevel(acc);
1393 xaccAccountBringUpToDate(acc);
1402 g_return_if_fail(GNC_IS_ACCOUNT(acc));
1404 qof_instance_set_destroying(acc, TRUE);
1412 compare_account_by_name (gconstpointer a, gconstpointer b)
1415 if (a && !b)
return 1;
1416 if (b && !a)
return -1;
1417 if (!a && !b)
return 0;
1418 priv_a = GET_PRIVATE((
Account*)a);
1419 priv_b = GET_PRIVATE((
Account*)b);
1420 if ((priv_a->accountCode && strlen (priv_a->accountCode)) ||
1421 (priv_b->accountCode && strlen (priv_b->accountCode)))
1422 return g_strcmp0 (priv_a->accountCode, priv_b->accountCode);
1423 return g_strcmp0 (priv_a->accountName, priv_b->accountName);
1427 xaccAcctChildrenEqual(
const GList *na,
1429 gboolean check_guids)
1431 if ((!na && nb) || (na && !nb))
1433 PINFO (
"only one has accounts");
1436 if (g_list_length ((GList*)na) != g_list_length ((GList*)nb))
1438 PINFO (
"Accounts have different numbers of children");
1446 GList *node = g_list_find_custom ((GList*)nb, aa,
1447 (GCompareFunc)compare_account_by_name);
1451 PINFO (
"Unable to find matching child account.");
1463 PWARN (
"accounts %s and %s differ", sa, sb);
1479 if (!aa && !ab)
return TRUE;
1481 g_return_val_if_fail(GNC_IS_ACCOUNT(aa), FALSE);
1482 g_return_val_if_fail(GNC_IS_ACCOUNT(ab), FALSE);
1484 priv_aa = GET_PRIVATE(aa);
1485 priv_ab = GET_PRIVATE(ab);
1486 if (priv_aa->type != priv_ab->type)
1488 PWARN (
"types differ: %d vs %d", priv_aa->type, priv_ab->type);
1492 if (g_strcmp0(priv_aa->accountName, priv_ab->accountName) != 0)
1494 PWARN (
"names differ: %s vs %s", priv_aa->accountName, priv_ab->accountName);
1498 if (g_strcmp0(priv_aa->accountCode, priv_ab->accountCode) != 0)
1500 PWARN (
"codes differ: %s vs %s", priv_aa->accountCode, priv_ab->accountCode);
1504 if (g_strcmp0(priv_aa->description, priv_ab->description) != 0)
1506 PWARN (
"descriptions differ: %s vs %s", priv_aa->description, priv_ab->description);
1512 PWARN (
"commodities differ");
1520 PWARN (
"GUIDs differ");
1533 PWARN (
"kvp frames differ:\n%s\n\nvs\n\n%s", frame_a, frame_b);
1549 PWARN (
"starting balances differ: %s vs %s", str_a, str_b);
1558 priv_ab->starting_cleared_balance))
1566 PWARN (
"starting cleared balances differ: %s vs %s", str_a, str_b);
1575 priv_ab->starting_reconciled_balance))
1583 PWARN (
"starting reconciled balances differ: %s vs %s", str_a, str_b);
1599 PWARN (
"balances differ: %s vs %s", str_a, str_b);
1615 PWARN (
"cleared balances differ: %s vs %s", str_a, str_b);
1623 if (!
gnc_numeric_equal(priv_aa->reconciled_balance, priv_ab->reconciled_balance))
1631 PWARN (
"reconciled balances differ: %s vs %s", str_a, str_b);
1642 GList *la = priv_aa->splits;
1643 GList *lb = priv_ab->splits;
1645 if ((la && !lb) || (!la && lb))
1647 PWARN (
"only one has splits");
1661 PWARN (
"splits differ");
1669 if ((la != NULL) || (lb != NULL))
1671 PWARN (
"number of splits differs");
1677 if (!xaccAcctChildrenEqual(priv_aa->children, priv_ab->children, check_guids))
1679 PWARN (
"children differ");
1693 g_return_if_fail(GNC_IS_ACCOUNT(acc));
1698 priv = GET_PRIVATE(acc);
1699 priv->sort_dirty = TRUE;
1707 g_return_if_fail(GNC_IS_ACCOUNT(acc));
1712 priv = GET_PRIVATE(acc);
1713 priv->balance_dirty = TRUE;
1725 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
1726 g_return_val_if_fail(GNC_IS_SPLIT(s), FALSE);
1728 priv = GET_PRIVATE(acc);
1729 node = g_list_find(priv->splits, s);
1733 if (qof_instance_get_editlevel(acc) == 0)
1735 priv->splits = g_list_insert_sorted(priv->splits, s,
1740 priv->splits = g_list_prepend(priv->splits, s);
1741 priv->sort_dirty = TRUE;
1749 priv->balance_dirty = TRUE;
1761 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
1762 g_return_val_if_fail(GNC_IS_SPLIT(s), FALSE);
1764 priv = GET_PRIVATE(acc);
1765 node = g_list_find(priv->splits, s);
1769 priv->splits = g_list_delete_link(priv->splits, node);
1775 priv->balance_dirty = TRUE;
1785 g_return_if_fail(GNC_IS_ACCOUNT(acc));
1787 priv = GET_PRIVATE(acc);
1788 if (!priv->sort_dirty || (!force && qof_instance_get_editlevel(acc) > 0))
1790 priv->splits = g_list_sort(priv->splits, (GCompareFunc)
xaccSplitOrder);
1791 priv->sort_dirty = FALSE;
1792 priv->balance_dirty = TRUE;
1796 xaccAccountBringUpToDate(
Account *acc)
1812 g_return_if_fail(GNC_IS_ACCOUNT(acc));
1813 g_return_if_fail(guid);
1816 PINFO(
"acct=%p", acc);
1818 qof_instance_set_guid (&acc->inst, guid);
1819 qof_instance_set_dirty(&acc->inst);
1830 if (!guid || !book)
return NULL;
1843 g_return_if_fail(GNC_IS_ACCOUNT(acc));
1845 priv = GET_PRIVATE(acc);
1854 g_return_if_fail(GNC_IS_ACCOUNT(acc));
1866 g_return_if_fail(GNC_IS_ACCOUNT(acc));
1868 priv = GET_PRIVATE(acc);
1870 for (node = priv->children; node; node = node->next)
1882 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), NULL);
1884 return GET_PRIVATE(acc)->policy;
1892 g_return_if_fail(GNC_IS_ACCOUNT(acc));
1894 priv = GET_PRIVATE(acc);
1906 g_return_if_fail(GNC_IS_ACCOUNT(acc));
1907 g_return_if_fail(GNC_IS_LOT(lot));
1909 priv = GET_PRIVATE(acc);
1910 g_return_if_fail(priv->lots);
1912 ENTER (
"(acc=%p, lot=%p)", acc, lot);
1913 priv->lots = g_list_remove(priv->lots, lot);
1916 LEAVE (
"(acc=%p, lot=%p)", acc, lot);
1927 g_return_if_fail(GNC_IS_ACCOUNT(acc));
1928 g_return_if_fail(GNC_IS_LOT(lot));
1932 if (lot_account == acc)
1935 ENTER (
"(acc=%p, lot=%p)", acc, lot);
1940 old_acc = lot_account;
1941 opriv = GET_PRIVATE(old_acc);
1942 opriv->lots = g_list_remove(opriv->lots, lot);
1945 priv = GET_PRIVATE(acc);
1946 priv->lots = g_list_prepend(priv->lots, lot);
1947 gnc_lot_set_account(lot, acc);
1957 LEAVE (
"(acc=%p, lot=%p)", acc, lot);
1963 xaccPreSplitMove (
Split *split, gpointer dummy)
1973 xaccSplitSetAccount(split, accto);
1985 g_return_if_fail(GNC_IS_ACCOUNT(accfrom));
1986 g_return_if_fail(GNC_IS_ACCOUNT(accto));
1989 from_priv = GET_PRIVATE(accfrom);
1990 if (!from_priv->splits || accfrom == accto)
1995 ENTER (
"(accfrom=%p, accto=%p)", accfrom, accto);
2000 g_list_foreach(from_priv->splits, (GFunc)xaccPreSplitMove, NULL);
2017 g_list_foreach(from_priv->splits, (GFunc)xaccPostSplitMove, (gpointer)accto);
2020 g_assert(from_priv->splits == NULL);
2021 g_assert(from_priv->lots == NULL);
2025 LEAVE (
"(accfrom=%p, accto=%p)", accfrom, accto);
2066 if (NULL == acc)
return;
2068 priv = GET_PRIVATE(acc);
2069 if (qof_instance_get_editlevel(acc) > 0)
return;
2070 if (!priv->balance_dirty)
return;
2074 balance = priv->starting_balance;
2075 cleared_balance = priv->starting_cleared_balance;
2076 reconciled_balance = priv->starting_reconciled_balance;
2078 PINFO (
"acct=%s starting baln=%" G_GINT64_FORMAT
"/%" G_GINT64_FORMAT,
2079 priv->accountName, balance.num, balance.denom);
2080 for (lp = priv->splits; lp; lp = lp->next)
2085 balance = gnc_numeric_add_fixed(balance, amt);
2087 if (
NREC != split->reconciled)
2089 cleared_balance = gnc_numeric_add_fixed(cleared_balance, amt);
2092 if (
YREC == split->reconciled ||
2093 FREC == split->reconciled)
2095 reconciled_balance =
2096 gnc_numeric_add_fixed(reconciled_balance, amt);
2099 split->balance = balance;
2100 split->cleared_balance = cleared_balance;
2101 split->reconciled_balance = reconciled_balance;
2105 priv->balance = balance;
2106 priv->cleared_balance = cleared_balance;
2107 priv->reconciled_balance = reconciled_balance;
2108 priv->balance_dirty = FALSE;
2127 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
2136 char *endptr = NULL;
2140 if ( aa && !ab )
return -1;
2141 if ( !aa && ab )
return +1;
2142 if ( !aa && !ab )
return 0;
2144 priv_aa = GET_PRIVATE(aa);
2145 priv_ab = GET_PRIVATE(ab);
2148 da = priv_aa->accountCode;
2149 db = priv_ab->accountCode;
2152 la = strtoul (da, &endptr, 36);
2153 if ((*da !=
'\0') && (*endptr ==
'\0'))
2155 lb = strtoul (db, &endptr, 36);
2156 if ((*db !=
'\0') && (*endptr ==
'\0'))
2158 if (la < lb)
return -1;
2159 if (la > lb)
return +1;
2164 result = g_strcmp0 (da, db);
2170 if (-1 == revorder[0])
2175 revorder [typeorder[i]] = i;
2184 if (ta < tb)
return -1;
2185 if (ta > tb)
return +1;
2188 da = priv_aa->accountName;
2189 db = priv_ab->accountName;
2213 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2217 priv = GET_PRIVATE(acc);
2218 if (priv->type == tip)
2223 priv->balance_dirty = TRUE;
2234 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2235 g_return_if_fail(str);
2238 priv = GET_PRIVATE(acc);
2239 if (g_strcmp0(str, priv->accountName) == 0)
2243 CACHE_REPLACE(priv->accountName, str);
2254 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2257 priv = GET_PRIVATE(acc);
2258 if (g_strcmp0(str, priv->accountCode) == 0)
2262 CACHE_REPLACE(priv->accountCode, str ? str :
"");
2273 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2276 priv = GET_PRIVATE(acc);
2277 if (g_strcmp0(str, priv->description) == 0)
2281 CACHE_REPLACE(priv->description, str ? str :
"");
2289 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2294 gchar *tmp = g_strstrip(g_strdup(str));
2296 strlen(tmp) ? kvp_value_new_string(tmp) : NULL);
2310 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2315 gchar *tmp = g_strstrip(g_strdup(str));
2317 strlen(tmp) ? kvp_value_new_string(tmp) : NULL);
2331 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2336 gchar *tmp = g_strstrip(g_strdup(str));
2338 strlen(tmp) ? kvp_value_new_string(tmp) : NULL);
2354 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2355 g_return_if_fail(GNC_IS_ACCOUNT(parent));
2357 parent_acc = GNC_ACCOUNT(parent);
2361 mark_account (parent_acc);
2370 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2375 gchar *tmp = g_strstrip(g_strdup(str));
2377 strlen(tmp) ? kvp_value_new_string(tmp) : NULL);
2395 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2396 g_return_if_fail(GNC_IS_COMMODITY(com));
2399 priv = GET_PRIVATE(acc);
2400 if (com == priv->commodity)
2405 priv->commodity = com;
2408 priv->non_standard_scu = FALSE;
2411 for (lp = priv->splits; lp; lp = lp->next)
2421 priv->sort_dirty = TRUE;
2422 priv->balance_dirty = TRUE;
2439 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2441 priv = GET_PRIVATE(acc);
2443 priv->commodity_scu = scu;
2445 priv->non_standard_scu = TRUE;
2453 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0);
2454 return GET_PRIVATE(acc)->commodity_scu;
2462 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0);
2464 priv = GET_PRIVATE(acc);
2465 if (priv->non_standard_scu || !priv->commodity)
2466 return priv->commodity_scu;
2475 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2477 priv = GET_PRIVATE(acc);
2478 if (priv->non_standard_scu == flag)
2481 priv->non_standard_scu = flag;
2489 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0);
2490 return GET_PRIVATE(acc)->non_standard_scu;
2504 if ((!acc) || (!currency))
return;
2509 kvp_value_new_string(
string));
2532 g_assert(GNC_IS_ACCOUNT(new_parent));
2533 g_assert(GNC_IS_ACCOUNT(child));
2536 ppriv = GET_PRIVATE(new_parent);
2537 cpriv = GET_PRIVATE(child);
2538 old_parent = cpriv->parent;
2539 if (old_parent == new_parent)
2561 PWARN (
"reparenting accounts across books is not correctly supported\n");
2570 cpriv->parent = new_parent;
2571 ppriv->children = g_list_append(ppriv->children, child);
2572 qof_instance_set_dirty(&new_parent->inst);
2573 qof_instance_set_dirty(&child->inst);
2596 if (!parent)
return;
2598 ppriv = GET_PRIVATE(parent);
2599 cpriv = GET_PRIVATE(child);
2601 if (cpriv->parent != parent)
2603 PERR (
"account not a child of parent");
2609 ed.idx = g_list_index(ppriv->children, child);
2611 ppriv->children = g_list_remove(ppriv->children, child);
2617 cpriv->parent = NULL;
2625 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), NULL);
2626 return GET_PRIVATE(acc)->parent;
2634 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), NULL);
2636 priv = GET_PRIVATE(acc);
2637 while (priv->parent)
2640 priv = GET_PRIVATE(acc);
2649 g_return_val_if_fail(GNC_IS_ACCOUNT(account), FALSE);
2650 return (GET_PRIVATE(account)->parent == NULL);
2656 g_return_val_if_fail(GNC_IS_ACCOUNT(account), NULL);
2657 return g_list_copy(GET_PRIVATE(account)->children);
2666 g_return_val_if_fail(GNC_IS_ACCOUNT(account), NULL);
2669 priv = GET_PRIVATE(account);
2670 if (!priv->children)
2672 return g_list_sort(g_list_copy(priv->children), (GCompareFunc)
xaccAccountOrder);
2678 g_return_val_if_fail(GNC_IS_ACCOUNT(account), 0);
2679 return g_list_length(GET_PRIVATE(account)->children);
2685 g_return_val_if_fail(GNC_IS_ACCOUNT(parent), -1);
2686 g_return_val_if_fail(GNC_IS_ACCOUNT(child), -1);
2687 return g_list_index(GET_PRIVATE(parent)->children, child);
2693 g_return_val_if_fail(GNC_IS_ACCOUNT(parent), NULL);
2694 return g_list_nth_data(GET_PRIVATE(parent)->children, num);
2704 g_return_val_if_fail(GNC_IS_ACCOUNT(account), 0);
2706 priv = GET_PRIVATE(account);
2707 for (node = priv->children; node; node = g_list_next(node))
2720 g_return_val_if_fail(GNC_IS_ACCOUNT(account), 0);
2722 priv = GET_PRIVATE(account);
2725 account = priv->parent;
2726 priv = GET_PRIVATE(account);
2738 gint depth = 0, child_depth;
2740 g_return_val_if_fail(GNC_IS_ACCOUNT(account), 0);
2742 priv = GET_PRIVATE(account);
2743 if (!priv->children)
2746 for (node = priv->children; node; node = g_list_next(node))
2749 depth = MAX(depth, child_depth);
2758 GList *child, *descendants;
2760 g_return_val_if_fail(GNC_IS_ACCOUNT(account), NULL);
2762 priv = GET_PRIVATE(account);
2763 if (!priv->children)
2767 for (child = priv->children; child; child = g_list_next(child))
2769 descendants = g_list_append(descendants, child->data);
2770 descendants = g_list_concat(descendants,
2780 GList *child, *children, *descendants;
2783 g_return_val_if_fail(GNC_IS_ACCOUNT(account), NULL);
2786 priv = GET_PRIVATE(account);
2787 if (!priv->children)
2791 children = g_list_sort(g_list_copy(priv->children), (GCompareFunc)
xaccAccountOrder);
2792 for (child = children; child; child = g_list_next(child))
2794 descendants = g_list_append(descendants, child->data);
2795 descendants = g_list_concat(descendants,
2798 g_list_free(children);
2809 g_return_val_if_fail(GNC_IS_ACCOUNT(parent), NULL);
2810 g_return_val_if_fail(name, NULL);
2813 ppriv = GET_PRIVATE(parent);
2814 for (node = ppriv->children; node; node = node->next)
2817 cpriv = GET_PRIVATE(child);
2818 if (g_strcmp0(cpriv->accountName, name) == 0)
2824 for (node = ppriv->children; node; node = node->next)
2842 g_return_val_if_fail(GNC_IS_ACCOUNT(parent), NULL);
2843 g_return_val_if_fail(code, NULL);
2846 ppriv = GET_PRIVATE(parent);
2847 for (node = ppriv->children; node; node = node->next)
2850 cpriv = GET_PRIVATE(child);
2851 if (g_strcmp0(cpriv->accountCode, code) == 0)
2857 for (node = ppriv->children; node; node = node->next)
2873 gnc_account_lookup_by_full_name_helper (
const Account *parent,
2880 g_return_val_if_fail(GNC_IS_ACCOUNT(parent), NULL);
2881 g_return_val_if_fail(names, NULL);
2884 ppriv = GET_PRIVATE(parent);
2885 for (node = ppriv->children; node; node = node->next)
2887 Account *account = node->data;
2889 priv = GET_PRIVATE(account);
2890 if (g_strcmp0(priv->accountName, names[0]) == 0)
2894 if (names[1] == NULL)
2898 if (!priv->children)
2902 found = gnc_account_lookup_by_full_name_helper(account, &names[1]);
2923 g_return_val_if_fail(GNC_IS_ACCOUNT(any_acc), NULL);
2924 g_return_val_if_fail(name, NULL);
2927 rpriv = GET_PRIVATE(root);
2928 while (rpriv->parent)
2930 root = rpriv->parent;
2931 rpriv = GET_PRIVATE(root);
2934 found = gnc_account_lookup_by_full_name_helper(root, names);
2947 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2948 g_return_if_fail(thunk);
2950 priv = GET_PRIVATE(acc);
2951 for (node = priv->children; node; node = node->next)
2953 thunk (node->data, user_data);
2966 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2967 g_return_if_fail(thunk);
2969 priv = GET_PRIVATE(acc);
2970 for (node = priv->children; node; node = node->next)
2973 thunk(child, user_data);
2988 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), NULL);
2989 g_return_val_if_fail(thunk, NULL);
2991 priv = GET_PRIVATE(acc);
2992 for (node = priv->children; node; node = node->next)
2995 result = thunk(child, user_data);
3012 return GET_PRIVATE(acc)->type;
3016 qofAccountGetTypeString (
const Account *acc)
3018 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), NULL);
3023 qofAccountSetType (
Account *acc,
const char *type_string)
3025 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3026 g_return_if_fail(type_string);
3033 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), NULL);
3034 return GET_PRIVATE(acc)->accountName;
3048 if (NULL == account)
3049 return g_strdup(
"");
3052 g_return_val_if_fail(GNC_IS_ACCOUNT(account), g_strdup(
""));
3055 priv = GET_PRIVATE(account);
3057 return g_strdup(
"");
3062 for (a = account; a; a = priv->parent)
3064 priv = GET_PRIVATE(a);
3070 names = g_malloc(level *
sizeof(gchar *));
3071 names[--level] = NULL;
3072 for (a = account; level > 0; a = priv->parent)
3074 priv = GET_PRIVATE(a);
3075 names[--level] = priv->accountName;
3079 fullname = g_strjoinv(account_separator, names);
3088 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), NULL);
3089 return GET_PRIVATE(acc)->accountCode;
3095 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), NULL);
3096 return GET_PRIVATE(acc)->description;
3102 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), NULL);
3103 return acc ? kvp_frame_get_string(acc->inst.kvp_data,
"color") : NULL;
3109 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0);
3110 return acc ? kvp_frame_get_string(acc->inst.kvp_data,
"filter") : NULL;
3116 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0);
3117 return acc ? kvp_frame_get_string(acc->inst.kvp_data,
"sort-order") : NULL;
3123 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), NULL);
3124 return acc ? kvp_frame_get_string(acc->inst.kvp_data,
"notes") : NULL;
3134 if (!acc)
return NULL;
3136 v = kvp_frame_get_slot(acc->inst.kvp_data,
"old-currency");
3137 if (!v)
return NULL;
3140 if (!s)
return NULL;
3144 return gnc_commodity_table_lookup_unique (table, s);
3150 if (!GNC_IS_ACCOUNT(acc))
3152 return GET_PRIVATE(acc)->commodity;
3165 const Account *parent_account = account;
3183 while (parent_account);
3195 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3197 priv = GET_PRIVATE(acc);
3198 priv->starting_balance = start_baln;
3199 priv->balance_dirty = TRUE;
3208 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3210 priv = GET_PRIVATE(acc);
3211 priv->starting_cleared_balance = start_baln;
3212 priv->balance_dirty = TRUE;
3221 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3223 priv = GET_PRIVATE(acc);
3224 priv->starting_reconciled_balance = start_baln;
3225 priv->balance_dirty = TRUE;
3231 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3232 return GET_PRIVATE(acc)->balance;
3238 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3239 return GET_PRIVATE(acc)->cleared_balance;
3245 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3246 return GET_PRIVATE(acc)->reconciled_balance;
3250 xaccAccountGetProjectedMinimumBalance (
const Account *acc)
3256 int seen_a_transaction = 0;
3258 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3260 priv = GET_PRIVATE(acc);
3262 for (node = g_list_last(priv->splits); node; node = node->prev)
3264 Split *split = node->data;
3266 if (!seen_a_transaction)
3269 seen_a_transaction = 1;
3299 gboolean found = FALSE;
3302 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3307 priv = GET_PRIVATE(acc);
3308 balance = priv->balance;
3326 while ( lp && !found )
3348 balance = gnc_numeric_zero();
3368 xaccAccountGetPresentBalance (
const Account *acc)
3374 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3376 priv = GET_PRIVATE(acc);
3378 for (node = g_list_last(priv->splits); node; node = node->prev)
3380 Split *split = node->data;
3386 return gnc_numeric_zero ();
3400 xaccAccountConvertBalanceToCurrency(
const Account *acc,
3412 book = gnc_account_get_book (acc);
3416 pdb, balance, balance_currency, new_currency);
3426 xaccAccountConvertBalanceToCurrencyAsOfDate(
const Account *acc,
3440 book = gnc_account_get_book (acc);
3447 pdb, balance, balance_currency, new_currency, ts);
3458 xaccAccountGetXxxBalanceInCurrency (
const Account *acc,
3459 xaccGetBalanceFn fn,
3465 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3466 g_return_val_if_fail(fn, gnc_numeric_zero());
3467 g_return_val_if_fail(GNC_IS_COMMODITY(report_currency), gnc_numeric_zero());
3469 priv = GET_PRIVATE(acc);
3471 balance = xaccAccountConvertBalanceToCurrency(acc, balance,
3478 xaccAccountGetXxxBalanceAsOfDateInCurrency(
Account *acc,
time64 date,
3479 xaccGetBalanceAsOfDateFn fn,
3484 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3485 g_return_val_if_fail(fn, gnc_numeric_zero());
3486 g_return_val_if_fail(GNC_IS_COMMODITY(report_commodity), gnc_numeric_zero());
3488 priv = GET_PRIVATE(acc);
3489 return xaccAccountConvertBalanceToCurrency(
3490 acc, fn(acc, date), priv->commodity, report_commodity);
3500 xaccGetBalanceFn fn;
3501 xaccGetBalanceAsOfDateFn asOfDateFn;
3512 xaccAccountBalanceHelper (
Account *acc, gpointer data)
3517 if (!cb->fn || !cb->currency)
3519 balance = xaccAccountGetXxxBalanceInCurrency (acc, cb->fn, cb->currency);
3526 xaccAccountBalanceAsOfDateHelper (
Account *acc, gpointer data)
3531 g_return_if_fail (cb->asOfDateFn && cb->currency);
3533 balance = xaccAccountGetXxxBalanceAsOfDateInCurrency (
3534 acc, cb->date, cb->asOfDateFn, cb->currency);
3553 xaccAccountGetXxxBalanceInCurrencyRecursive (
const Account *acc,
3554 xaccGetBalanceFn fn,
3556 gboolean include_children)
3560 if (!acc)
return gnc_numeric_zero ();
3561 if (!report_commodity)
3563 if (!report_commodity)
3564 return gnc_numeric_zero();
3566 balance = xaccAccountGetXxxBalanceInCurrency (acc, fn, report_commodity);
3570 if (include_children)
3577 cb.balance = balance;
3583 balance = cb.balance;
3590 xaccAccountGetXxxBalanceAsOfDateInCurrencyRecursive (
3596 g_return_val_if_fail(acc, gnc_numeric_zero());
3597 if (!report_commodity)
3599 if (!report_commodity)
3600 return gnc_numeric_zero();
3602 balance = xaccAccountGetXxxBalanceAsOfDateInCurrency(
3603 acc, date, fn, report_commodity);
3607 if (include_children)
3614 cb.balance = balance;
3620 balance = cb.balance;
3627 xaccAccountGetBalanceInCurrency (
const Account *acc,
3629 gboolean include_children)
3632 rc = xaccAccountGetXxxBalanceInCurrencyRecursive (
3634 PINFO(
" baln=%" G_GINT64_FORMAT
"/%" G_GINT64_FORMAT, rc.num, rc.denom);
3640 xaccAccountGetClearedBalanceInCurrency (
const Account *acc,
3642 gboolean include_children)
3644 return xaccAccountGetXxxBalanceInCurrencyRecursive (
3650 xaccAccountGetReconciledBalanceInCurrency (
const Account *acc,
3652 gboolean include_children)
3654 return xaccAccountGetXxxBalanceInCurrencyRecursive (
3660 xaccAccountGetPresentBalanceInCurrency (
const Account *acc,
3662 gboolean include_children)
3664 return xaccAccountGetXxxBalanceInCurrencyRecursive (
3665 acc, xaccAccountGetPresentBalance, report_commodity,
3670 xaccAccountGetProjectedMinimumBalanceInCurrency (
3673 gboolean include_children)
3675 return xaccAccountGetXxxBalanceInCurrencyRecursive (
3676 acc, xaccAccountGetProjectedMinimumBalance, report_commodity,
3681 xaccAccountGetBalanceAsOfDateInCurrency(
3683 gboolean include_children)
3685 return xaccAccountGetXxxBalanceAsOfDateInCurrencyRecursive (
3696 b1 = xaccAccountGetBalanceAsOfDateInCurrency(acc, t1, NULL, recurse);
3697 b2 = xaccAccountGetBalanceAsOfDateInCurrency(acc, t2, NULL, recurse);
3719 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), NULL);
3721 return GET_PRIVATE(acc)->splits;
3730 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0);
3746 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), NULL);
3747 return g_list_copy(GET_PRIVATE(acc)->lots);
3752 gboolean (*match_func)(
GNCLot *lot,
3753 gpointer user_data),
3754 gpointer user_data, GCompareFunc sort_func)
3758 GList *retval = NULL;
3760 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), NULL);
3762 priv = GET_PRIVATE(acc);
3763 for (lot_list = priv->lots; lot_list; lot_list = lot_list->next)
3765 GNCLot *lot = lot_list->data;
3771 if (match_func && !(match_func)(lot, user_data))
3776 retval = g_list_insert_sorted (retval, lot, sort_func);
3778 retval = g_list_prepend (retval, lot);
3786 gpointer (*proc)(
GNCLot *lot,
void *data),
void *data)
3790 gpointer result = NULL;
3792 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), NULL);
3793 g_return_val_if_fail(proc, NULL);
3795 priv = GET_PRIVATE(acc);
3796 for (node = priv->lots; node; node = node->next)
3797 if ((result = proc((
GNCLot *)node->data, data)))
3810 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
3811 return kvp_frame_get_gint64(acc->inst.kvp_data,
"tax-related");
3819 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3822 new_value = kvp_value_new_gint64 (tax_related);
3835 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), NULL);
3836 return kvp_frame_get_string(acc->inst.kvp_data,
"tax-US/code");
3842 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3849 kvp_frame_set_frame (acc->inst.kvp_data,
"/tax-US", frame);
3858 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), NULL);
3859 return kvp_frame_get_string(acc->inst.kvp_data,
3860 "tax-US/payer-name-source");
3866 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3870 "/tax-US/payer-name-source", source);
3880 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 1);
3881 copy_number = kvp_frame_get_gint64(acc->inst.kvp_data,
3882 "tax-US/copy-number");
3883 return (copy_number == 0) ? 1 : copy_number;
3889 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3892 if (copy_number != 0)
3901 "/tax-US/copy-number", value);
3916 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
3918 str = kvp_frame_get_string(acc->inst.kvp_data,
"placeholder");
3919 return (str && !strcmp(str,
"true"));
3925 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3929 "placeholder", val ?
"true" : NULL);
3937 GList *descendants, *node;
3940 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), PLACEHOLDER_NONE);
3944 for (node = descendants; node; node = node->next)
3947 ret = PLACEHOLDER_CHILD;
3951 g_list_free(descendants);
3963 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
3965 str = kvp_frame_get_string(acc->inst.kvp_data,
"hidden");
3966 return (str && !strcmp(str,
"true"));
3972 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3976 val ?
"true" : NULL);
3986 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
3990 priv = GET_PRIVATE(acc);
3991 while ((acc = priv->parent) != NULL)
3993 priv = GET_PRIVATE(acc);
4008 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4009 g_return_val_if_fail(GNC_IS_ACCOUNT(ancestor), FALSE);
4012 while (parent && parent != ancestor)
4013 parent = GET_PRIVATE(parent)->parent;
4015 return (parent == ancestor);
4024 #define GNC_RETURN_ENUM_AS_STRING(x) case (ACCT_TYPE_ ## x): return #x;
4031 GNC_RETURN_ENUM_AS_STRING(NONE);
4032 GNC_RETURN_ENUM_AS_STRING(BANK);
4033 GNC_RETURN_ENUM_AS_STRING(CASH);
4034 GNC_RETURN_ENUM_AS_STRING(CREDIT);
4035 GNC_RETURN_ENUM_AS_STRING(ASSET);
4036 GNC_RETURN_ENUM_AS_STRING(LIABILITY);
4037 GNC_RETURN_ENUM_AS_STRING(STOCK);
4038 GNC_RETURN_ENUM_AS_STRING(MUTUAL);
4039 GNC_RETURN_ENUM_AS_STRING(CURRENCY);
4040 GNC_RETURN_ENUM_AS_STRING(INCOME);
4041 GNC_RETURN_ENUM_AS_STRING(EXPENSE);
4042 GNC_RETURN_ENUM_AS_STRING(EQUITY);
4043 GNC_RETURN_ENUM_AS_STRING(RECEIVABLE);
4044 GNC_RETURN_ENUM_AS_STRING(PAYABLE);
4045 GNC_RETURN_ENUM_AS_STRING(ROOT);
4046 GNC_RETURN_ENUM_AS_STRING(TRADING);
4047 GNC_RETURN_ENUM_AS_STRING(CHECKING);
4048 GNC_RETURN_ENUM_AS_STRING(SAVINGS);
4049 GNC_RETURN_ENUM_AS_STRING(MONEYMRKT);
4050 GNC_RETURN_ENUM_AS_STRING(CREDITLINE);
4052 PERR (
"asked to translate unknown account type %d.\n", type);
4058 #undef GNC_RETURN_ENUM_AS_STRING
4060 #define GNC_RETURN_ON_MATCH(x) \
4061 if(g_strcmp0(#x, (str)) == 0) { *type = ACCT_TYPE_ ## x; return(TRUE); }
4067 GNC_RETURN_ON_MATCH(NONE);
4068 GNC_RETURN_ON_MATCH(BANK);
4069 GNC_RETURN_ON_MATCH(CASH);
4070 GNC_RETURN_ON_MATCH(CREDIT);
4071 GNC_RETURN_ON_MATCH(ASSET);
4072 GNC_RETURN_ON_MATCH(LIABILITY);
4073 GNC_RETURN_ON_MATCH(STOCK);
4074 GNC_RETURN_ON_MATCH(MUTUAL);
4075 GNC_RETURN_ON_MATCH(CURRENCY);
4076 GNC_RETURN_ON_MATCH(INCOME);
4077 GNC_RETURN_ON_MATCH(EXPENSE);
4078 GNC_RETURN_ON_MATCH(EQUITY);
4079 GNC_RETURN_ON_MATCH(RECEIVABLE);
4080 GNC_RETURN_ON_MATCH(PAYABLE);
4081 GNC_RETURN_ON_MATCH(ROOT);
4082 GNC_RETURN_ON_MATCH(TRADING);
4083 GNC_RETURN_ON_MATCH(CHECKING);
4084 GNC_RETURN_ON_MATCH(SAVINGS);
4085 GNC_RETURN_ON_MATCH(MONEYMRKT);
4086 GNC_RETURN_ON_MATCH(CREDITLINE);
4088 PERR(
"asked to translate unknown account type string %s.\n",
4089 str ? str :
"(null)");
4094 #undef GNC_RETURN_ON_MATCH
4140 return _(account_type_name [type]);
4188 PERR(
"bad account type: %d", type);
4253 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4255 priv = GET_PRIVATE(acc);
4268 if (!acc)
return FALSE;
4270 v = kvp_frame_get_value(acc->inst.kvp_data,
"reconcile-info/last-date");
4291 "/reconcile-info/last-date", last_date);
4301 int *months,
int *days)
4305 if (!acc)
return FALSE;
4307 v1 = kvp_frame_get_value(acc->inst.kvp_data,
4308 "reconcile-info/last-interval/months");
4309 v2 = kvp_frame_get_value(acc->inst.kvp_data,
4310 "reconcile-info/last-interval/days");
4333 frame = kvp_frame_get_frame_slash (acc->inst.kvp_data,
4334 "/reconcile-info/last-interval");
4352 if (!acc)
return FALSE;
4354 v = kvp_frame_get_value(acc->inst.kvp_data,
"reconcile-info/postpone/date");
4376 "reconcile-info/postpone/date", postpone_date);
4390 if (!acc)
return FALSE;
4392 v = kvp_frame_get_value(acc->inst.kvp_data,
4393 "reconcile-info/postpone/balance");
4398 *balance = kvp_value_get_numeric (v);
4413 "/reconcile-info/postpone/balance", balance);
4443 const char *str = NULL;
4444 if (!acc)
return default_value;
4446 str = kvp_frame_get_string(acc->inst.kvp_data,
4447 "reconcile-info/auto-interest-transfer");
4448 return str ? !strcmp(str,
"true") : default_value;
4462 "/reconcile-info/auto-interest-transfer",
4463 (option ?
"true" :
"false"));
4474 return acc ? kvp_frame_get_string(acc->inst.kvp_data,
"last-num") : NULL;
4497 g_return_val_if_fail (root, NULL);
4502 PERR (
"No currency specified!");
4506 accname = g_strconcat (_(
"Orphaned Gains"),
"-",
4522 _(
"Realized Gains or Losses from "
4523 "Commodity or Trading Accounts "
4524 "that haven't been recorded elsewhere."));
4539 KvpFrame *frame = qof_instance_get_slots (QOF_INSTANCE (acc));
4544 frame = kvp_frame_get_frame_slash (frame,
"/lot-mgmt/gains-act/");
4545 guid = kvp_frame_get_guid (frame, curr_name);
4553 kvp_frame_set_guid (frame, curr_name, guid);
4554 qof_instance_set_dirty (QOF_INSTANCE (acc));
4562 return gains_account;
4578 src ? kvp_value_new_string(src) : NULL);
4582 qof_instance_set_dirty(&acc->inst);
4592 if (!acc)
return NULL;
4596 KvpValue *value = kvp_frame_get_slot(acc->inst.kvp_data,
4597 "old-price-source");
4616 tz ? kvp_value_new_string(tz) : NULL);
4619 qof_instance_set_dirty(&acc->inst);
4629 if (!acc)
return NULL;
4633 KvpValue *value = kvp_frame_get_slot(acc->inst.kvp_data,
"old-quote-tz");
4651 "/reconcile-info/include-children", status);
4666 return acc ? kvp_frame_get_gint64(acc->inst.kvp_data,
4667 "reconcile-info/include-children") : FALSE;
4679 finder_help_function(
const Account *acc,
const char *description,
4686 if (split) *split = NULL;
4687 if (trans) *trans = NULL;
4690 if (acc == NULL)
return;
4695 priv = GET_PRIVATE(acc);
4696 for (slp = g_list_last(priv->splits); slp; slp = slp->prev)
4698 Split *lsplit = slp->data;
4703 if (split) *split = lsplit;
4704 if (trans) *trans = ltrans;
4716 finder_help_function(acc, description, &split, NULL);
4731 finder_help_function(acc, description, NULL, &trans);
4742 GList *children, *node;
4745 g_return_if_fail(GNC_IS_ACCOUNT(to_parent));
4746 g_return_if_fail(GNC_IS_ACCOUNT(from_parent));
4749 from_priv = GET_PRIVATE(from_parent);
4750 if (!from_priv->children)
4754 children = g_list_copy(from_priv->children);
4755 for (node = children; node; node = g_list_next(node))
4757 g_list_free(children);
4767 GList *node_a, *node_b, *work, *worker;
4769 g_return_if_fail(GNC_IS_ACCOUNT(parent));
4771 ppriv = GET_PRIVATE(parent);
4772 for (node_a = ppriv->children; node_a; node_a = node_a->next)
4774 Account *acc_a = node_a->data;
4776 priv_a = GET_PRIVATE(acc_a);
4777 for (node_b = node_a->next; node_b; node_b = g_list_next(node_b))
4779 Account *acc_b = node_b->data;
4781 priv_b = GET_PRIVATE(acc_b);
4782 if (0 !=
null_strcmp(priv_a->accountName, priv_b->accountName))
4784 if (0 !=
null_strcmp(priv_a->accountCode, priv_b->accountCode))
4786 if (0 !=
null_strcmp(priv_a->description, priv_b->description))
4796 if (priv_a->type != priv_b->type)
4800 if (priv_b->children)
4802 work = g_list_copy(priv_b->children);
4803 for (worker = work; worker; worker = g_list_next(worker))
4815 while (priv_b->splits)
4816 xaccSplitSetAccount (priv_b->splits->data, acc_a);
4820 node_b = g_list_previous(node_b);
4839 for (lp = splits; lp; lp = lp->next)
4841 Split *s = lp->data;
4857 priv = GET_PRIVATE(account);
4864 if (trans == NULL)
return FALSE;
4866 if (trans->marker < stage)
4868 trans->marker = stage;
4875 static void do_one_split (
Split *s, gpointer data)
4881 static void do_one_account (
Account *account, gpointer data)
4884 g_list_foreach(priv->splits, (GFunc)do_one_split, NULL);
4894 g_list_foreach(descendants, (GFunc)do_one_account, NULL);
4895 g_list_free(descendants);
4901 TransactionCallback thunk,
4913 priv = GET_PRIVATE(acc);
4914 for (split_p = priv->splits; split_p; split_p = next)
4920 next = g_list_next(split_p);
4924 if (trans && (trans->marker < stage))
4926 trans->marker = stage;
4929 retval = thunk(trans, cb_data);
4930 if (retval)
return retval;
4941 TransactionCallback thunk,
4945 GList *acc_p, *split_p;
4953 priv = GET_PRIVATE(acc);
4954 for (acc_p = priv->children; acc_p; acc_p = g_list_next(acc_p))
4958 if (retval)
return retval;
4962 for (split_p = priv->splits; split_p; split_p = g_list_next(split_p))
4966 if (trans && (trans->marker < stage))
4968 trans->marker = stage;
4971 retval = thunk(trans, cb_data);
4972 if (retval)
return retval;
4988 if (!acc || !proc)
return 0;
4999 if (!acc || !proc)
return 0;
5022 #define IMAP_FRAME "import-map"
5023 #define IMAP_FRAME_BAYES "import-map-bayes"
5028 const char *key,
Account *acc);
5040 if (!acc)
return NULL;
5041 frame = qof_instance_get_slots (QOF_INSTANCE (acc));
5042 g_return_val_if_fail (frame != NULL, NULL);
5043 g_return_val_if_fail (frame != NULL, NULL);
5046 imap->frame = frame;
5052 imap->book = gnc_account_get_book (acc);
5060 const char *category,
5066 if (!imap || !key)
return NULL;
5074 category, key, NULL);
5075 if (!value)
return NULL;
5084 const char *category,
5090 if (!imap || !key || !acc || (strlen (key) == 0))
return;
5096 g_return_if_fail (acc != NULL);
5099 g_return_if_fail (value != NULL);
5102 qof_instance_set_dirty (QOF_INSTANCE (imap->acc));
5136 buildTokenInfo(
const char *key,
KvpValue *value, gpointer data)
5152 this_account->account_name = (
char*)key;
5166 double product_difference;
5173 #define PROBABILITY_FACTOR 100000
5175 buildProbabilities(gpointer key, gpointer value, gpointer data)
5177 GHashTable *final_probabilities = (GHashTable*)data;
5184 gint32 probability =
5185 (account_p->product /
5186 (account_p->product + account_p->product_difference))
5187 * PROBABILITY_FACTOR;
5189 PINFO(
"P('%s') = '%d'\n", (
char*)key, probability);
5191 g_hash_table_insert(final_probabilities, key, GINT_TO_POINTER(probability));
5196 freeProbabilities(gpointer key, gpointer value, gpointer data)
5220 highestProbability(gpointer key, gpointer value, gpointer data)
5225 if (GPOINTER_TO_INT(value) > account_i->probability)
5228 account_i->probability = GPOINTER_TO_INT(value);
5229 account_i->account_name = key;
5234 #define threshold (.90 * PROBABILITY_FACTOR)
5242 GList *current_token;
5245 GList *current_account_token;
5253 GHashTable *running_probabilities = g_hash_table_new(g_str_hash,
5255 GHashTable *final_probabilities = g_hash_table_new(g_str_hash,
5266 PINFO(
"imap is null, returning null");
5274 for (current_token = tokens; current_token;
5275 current_token = current_token->next)
5280 PINFO(
"token: '%s'", (
char*)current_token->data);
5287 (
char*)current_token->data, NULL);
5301 PERR(
"token '%s' has no accounts", (
char*)current_token->data);
5315 for (current_account_token = tokenInfo.
accounts; current_account_token;
5316 current_account_token = current_account_token->next)
5321 PINFO(
"account_c->account_name('%s'), "
5322 "account_c->token_count('%ld')/total_count('%ld')",
5323 account_c->account_name, (
long)account_c->
token_count,
5324 (long)tokenInfo.total_count);
5326 account_p = g_hash_table_lookup(running_probabilities,
5327 account_c->account_name);
5334 account_p->product = (((double)account_c->
token_count /
5335 (
double)tokenInfo.total_count)
5336 * account_p->product);
5337 account_p->product_difference =
5339 (double)tokenInfo.total_count))
5340 * account_p->product_difference;
5341 PINFO(
"product == %f, product_difference == %f",
5342 account_p->product, account_p->product_difference);
5347 PINFO(
"adding a new entry for this account");
5352 account_p->product = ((double)account_c->
token_count /
5353 (
double)tokenInfo.total_count);
5354 account_p->product_difference =
5356 (double)tokenInfo.total_count);
5358 PINFO(
"product == %f, product_difference == %f",
5359 account_p->product, account_p->product_difference);
5363 g_hash_table_insert(running_probabilities,
5364 account_c->account_name, account_p);
5369 for (current_account_token = tokenInfo.
accounts; current_account_token;
5370 current_account_token = current_account_token->next)
5382 g_hash_table_foreach(running_probabilities, buildProbabilities,
5383 final_probabilities);
5387 g_hash_table_foreach(final_probabilities, highestProbability, &account_i);
5390 g_hash_table_foreach(running_probabilities, freeProbabilities, NULL);
5393 g_hash_table_destroy(running_probabilities);
5394 g_hash_table_destroy(final_probabilities);
5396 PINFO(
"highest P('%s') = '%d'",
5397 account_i.account_name ? account_i.account_name :
"(null)",
5398 account_i.probability);
5401 if (account_i.probability >= threshold)
5403 PINFO(
"found match");
5406 account_i.account_name);
5422 GList *current_token;
5425 char* account_fullname;
5438 g_return_if_fail (acc != NULL);
5442 PINFO(
"account name: '%s'\n", account_fullname);
5445 for (current_token = g_list_first(tokens); current_token;
5446 current_token = current_token->next)
5452 if (!current_token->data || (*((
char*)current_token->data) ==
'\0'))
5458 PINFO(
"adding token '%s'\n", (
char*)current_token->data);
5462 (
char*)current_token->data,
5472 PINFO(
"found existing value of '%ld'\n",
5483 new_value = kvp_value_new_gint64(token_count);
5490 (
char*)current_token->data,
5499 qof_instance_set_dirty (QOF_INSTANCE (imap->acc));
5501 g_free(account_fullname);
5510 gnc_account_book_end(
QofBook* book)
5512 Account *root_account = gnc_book_get_root_account(book);
5528 DI(.e_type = ) GNC_ID_ACCOUNT,
5531 DI(.book_begin = ) NULL,
5532 DI(.book_end = ) gnc_account_book_end,
5540 gboolean xaccAccountRegister (
void)
5545 ACCOUNT_NAME_, QOF_TYPE_STRING,
5550 ACCOUNT_CODE_, QOF_TYPE_STRING,
5555 ACCOUNT_DESCRIPTION_, QOF_TYPE_STRING,
5560 ACCOUNT_COLOR_, QOF_TYPE_STRING,
5565 ACCOUNT_FILTER_, QOF_TYPE_STRING,
5570 ACCOUNT_SORT_ORDER_, QOF_TYPE_STRING,
5575 ACCOUNT_NOTES_, QOF_TYPE_STRING,
5580 ACCOUNT_PRESENT_, QOF_TYPE_NUMERIC,
5584 ACCOUNT_BALANCE_, QOF_TYPE_NUMERIC,
5588 ACCOUNT_CLEARED_, QOF_TYPE_NUMERIC,
5592 ACCOUNT_RECONCILED_, QOF_TYPE_NUMERIC,
5596 ACCOUNT_TYPE_, QOF_TYPE_STRING,
5601 ACCOUNT_FUTURE_MINIMUM_, QOF_TYPE_NUMERIC,
5605 ACCOUNT_TAX_RELATED, QOF_TYPE_BOOLEAN,
5610 ACCOUNT_SCU, QOF_TYPE_INT32,
5615 ACCOUNT_NSCU, QOF_TYPE_BOOLEAN,
5620 ACCOUNT_PARENT, GNC_ID_ACCOUNT,
5629 QOF_PARAM_GUID, QOF_TYPE_GUID,
5633 ACCOUNT_KVP, QOF_TYPE_KVP,
5648 utest_account_get_private (Account *acc)
5650 return GET_PRIVATE (acc);
5654 _utest_account_fill_functions(
void)
5658 func->get_private = utest_account_get_private;
5659 func->coll_get_root_account = gnc_coll_get_root_account;
5660 func->xaccFreeAccountChildren = xaccFreeAccountChildren;
5661 func->xaccFreeAccount = xaccFreeAccount;
5662 func->qofAccountSetParent = qofAccountSetParent;
5663 func->gnc_account_lookup_by_full_name_helper =
5664 gnc_account_lookup_by_full_name_helper;
void xaccAccountSetType(Account *acc, GNCAccountType tip)
int qof_instance_version_cmp(const QofInstance *left, const QofInstance *right)
gnc_commodity * gnc_commodity_table_insert(gnc_commodity_table *table, gnc_commodity *comm)
Account * gnc_account_get_parent(const Account *acc)
void xaccAccountSetFilter(Account *acc, const char *str)
void xaccAccountSetSortOrder(Account *acc, const char *str)
gint xaccAccountForEachTransaction(const Account *acc, TransactionCallback proc, void *data)
int xaccAccountTreeForEachTransaction(Account *acc, TransactionCallback proc, void *data)
gint xaccSplitOrder(const Split *sa, const Split *sb)
gnc_commodity_table * gnc_commodity_table_get_table(QofBook *book)
gboolean gnc_numeric_equal(gnc_numeric a, gnc_numeric b)
int gnc_account_tree_staged_transaction_traversal(const Account *acc, unsigned int stage, TransactionCallback thunk, void *cb_data)
const char * xaccAccountGetLastNum(const Account *acc)
gboolean gnc_commodity_is_currency(const gnc_commodity *cm)
int gnc_commodity_get_fraction(const gnc_commodity *cm)
void gnc_account_append_child(Account *new_parent, Account *child)
const GncGUID * qof_instance_get_guid(gconstpointer)
gpointer xaccAccountForEachLot(const Account *acc, gpointer(*proc)(GNCLot *lot, gpointer user_data), gpointer user_data)
time64 xaccTransGetDate(const Transaction *trans)
GList * gnc_account_get_descendants_sorted(const Account *account)
gint gnc_account_n_descendants(const Account *account)
gint64 xaccAccountGetTaxUSCopyNumber(const Account *acc)
gboolean gnc_account_is_root(const Account *account)
SplitList * xaccAccountGetSplitList(const Account *acc)
const char * gnc_commodity_get_mnemonic(const gnc_commodity *cm)
gboolean xaccAccountGetNonStdSCU(const Account *acc)
int xaccAccountGetCommoditySCUi(const Account *acc)
gnc_commodity * DxaccAccountGetCurrency(const Account *acc)
void gnc_account_foreach_descendant(const Account *acc, AccountCb thunk, gpointer user_data)
void xaccAccountSetNotes(Account *acc, const char *str)
QofBook * qof_instance_get_book(gconstpointer)
gboolean xaccAccountIsPriced(const Account *acc)
gboolean qof_collection_is_dirty(const QofCollection *col)
time64 gnc_time64_get_today_end(void)
gboolean xaccTransIsOpen(const Transaction *trans)
a simple price database for gnucash
QofInstance * qof_collection_lookup_entity(const QofCollection *, const GncGUID *)
int safe_utf8_collate(const char *da, const char *db)
#define PINFO(format, args...)
const char * xaccAccountGetFilter(const Account *acc)
GNCAccountType xaccAccountGetType(const Account *acc)
gboolean xaccSplitDestroy(Split *split)
void xaccAccountSetMark(Account *acc, short m)
QofBackendError
The errors that can be reported to the GUI & other front-end users.
int xaccAccountGetCommoditySCU(const Account *acc)
const char * xaccAccountGetCode(const Account *acc)
void xaccAccountSetReconcileLastDate(Account *acc, time64 last_date)
Account * gnc_account_create_root(QofBook *book)
void gnc_commodity_decrement_usage_count(gnc_commodity *cm)
void xaccAccountSetTaxRelated(Account *acc, gboolean tax_related)
gboolean qof_instance_get_destroying(gconstpointer ptr)
void gnc_imap_add_account_bayes(GncImportMatchMap *imap, GList *tokens, Account *acc)
gint kvp_frame_compare(const KvpFrame *fa, const KvpFrame *fb)
void qof_class_register(QofIdTypeConst obj_name, QofSortFunc default_sort_fcn, const QofParam *params)
KvpFrame * kvp_frame_copy(const KvpFrame *frame)
gboolean gnc_commodity_equal(const gnc_commodity *a, const gnc_commodity *b)
void xaccAccountSortSplits(Account *acc, gboolean force)
#define kvp_frame_set_gnc_numeric
void xaccAccountSetCode(Account *acc, const char *str)
gpointer gnc_account_foreach_descendant_until(const Account *acc, AccountCb2 thunk, gpointer user_data)
void gnc_account_set_policy(Account *acc, GNCPolicy *policy)
void xaccAccountSetReconcileLastInterval(Account *acc, int months, int days)
gnc_numeric gnc_numeric_add(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Use a 64-bit unsigned int timespec.
void kvp_frame_set_gint64(KvpFrame *frame, const gchar *path, gint64 ival)
gboolean gnc_account_remove_split(Account *acc, Split *s)
guint32 xaccAccountTypesValid(void)
gboolean gnc_numeric_zero_p(gnc_numeric a)
const char * xaccAccountTypeEnumAsString(GNCAccountType type)
GList * gnc_account_list_name_violations(QofBook *book, const gchar *separator)
void xaccAccountInsertLot(Account *acc, GNCLot *lot)
Transaction * xaccSplitGetParent(const Split *split)
API for Transactions and Splits (journal entries)
gchar * guid_to_string_buff(const GncGUID *guid, gchar *buff)
gpointer(* QofAccessFunc)(gpointer object, const QofParam *param)
gint gnc_numeric_compare(gnc_numeric a, gnc_numeric b)
#define QOF_OBJECT_VERSION
Account * gnc_imap_find_account_bayes(GncImportMatchMap *imap, GList *tokens)
gchar * gnc_numeric_to_string(gnc_numeric n)
void xaccAccountMoveAllSplits(Account *accfrom, Account *accto)
gboolean qof_commit_edit(QofInstance *inst)
#define PERR(format, args...)
void gnc_account_set_sort_dirty(Account *acc)
#define ENTER(format, args...)
gnc_numeric xaccSplitGetBalance(const Split *s)
void xaccAccountSetLastNum(Account *acc, const char *num)
KvpFrame * kvp_frame_set_value(KvpFrame *frame, const gchar *path, const KvpValue *value)
gnc_numeric xaccAccountGetClearedBalance(const Account *acc)
void qof_collection_foreach(const QofCollection *, QofInstanceForeachCB, gpointer user_data)
GNCPriceDB * gnc_pricedb_get_db(QofBook *book)
void kvp_frame_delete(KvpFrame *frame)
void kvp_frame_set_slot_path(KvpFrame *frame, KvpValue *value, const gchar *first_key,...)
gint64 kvp_value_get_gint64(const KvpValue *value)
gnc_numeric gnc_pricedb_convert_balance_latest_price(GNCPriceDB *pdb, gnc_numeric balance, const gnc_commodity *balance_currency, const gnc_commodity *new_currency)
gboolean xaccAccountGetReconcilePostponeDate(const Account *acc, time64 *postpone_date)
void xaccAccountDestroy(Account *acc)
gboolean xaccAccountIsHidden(const Account *acc)
gboolean xaccSplitEqual(const Split *sa, const Split *sb, gboolean check_guids, gboolean check_balances, gboolean check_txn_splits)
Account * gnc_account_lookup_by_name(const Account *parent, const char *name)
#define PWARN(format, args...)
void gnc_account_remove_child(Account *parent, Account *child)
int xaccAccountOrder(const Account *aa, const Account *ab)
const char * xaccAccountGetColor(const Account *acc)
Split * xaccAccountFindSplitByDesc(const Account *acc, const char *description)
void qof_instance_init_data(QofInstance *, QofIdType, QofBook *)
gint timespec_cmp(const Timespec *ta, const Timespec *tb)
gboolean qof_begin_edit(QofInstance *inst)
#define xaccAccountGetGUID(X)
gboolean xaccAccountIsAssetLiabType(GNCAccountType t)
void xaccClearMarkDown(Account *acc, short val)
GNCAccountType xaccAccountStringToEnum(const char *str)
void xaccSplitSetAmount(Split *s, gnc_numeric amt)
gchar * gnc_account_get_full_name(const Account *account)
void xaccAccountSetPlaceholder(Account *acc, gboolean val)
char * kvp_value_get_string(const KvpValue *value)
gboolean xaccAccountTypesCompatible(GNCAccountType parent_type, GNCAccountType child_type)
gchar * gnc_account_name_violations_errmsg(const gchar *separator, GList *invalid_account_names)
gboolean xaccTransactionTraverse(Transaction *trans, int stage)
void xaccAccountSetColor(Account *acc, const char *str)
Transaction * xaccAccountFindTransByDesc(const Account *acc, const char *description)
void gnc_account_set_balance_dirty(Account *acc)
void gnc_account_foreach_child(const Account *acc, AccountCb thunk, gpointer user_data)
Account * gnc_account_lookup_by_code(const Account *parent, const char *code)
void gnc_account_tree_begin_staged_transaction_traversals(Account *account)
void dxaccAccountSetPriceSrc(Account *acc, const char *src)
#define GUID_ENCODING_LENGTH
void xaccAccountBeginStagedTransactionTraversals(const Account *account)
void gnc_commodity_increment_usage_count(gnc_commodity *cm)
GNCPlaceholderType xaccAccountGetDescendantPlaceholder(const Account *acc)
const char * xaccAccountGetDescription(const Account *acc)
void gnc_account_set_start_reconciled_balance(Account *acc, const gnc_numeric start_baln)
const char * dxaccAccountGetQuoteTZ(const Account *acc)
void xaccAccountClearReconcilePostpone(Account *acc)
const char * xaccAccountGetTaxUSPayerNameSource(const Account *acc)
void xaccSplitsBeginStagedTransactionTraversals(GList *splits)
gint null_strcmp(const gchar *da, const gchar *db)
GList * gnc_account_get_children_sorted(const Account *account)
LotList * xaccAccountGetLotList(const Account *acc)
void kvp_frame_set_slot_nc(KvpFrame *frame, const gchar *key, KvpValue *value)
void xaccAccountRecomputeBalance(Account *acc)
int(* QofSortFunc)(gconstpointer, gconstpointer)
const char * xaccTransGetDescription(const Transaction *trans)
Account * gnc_account_lookup_by_full_name(const Account *any_acc, const gchar *name)
void xaccAccountSetReconcilePostponeDate(Account *acc, time64 postpone_date)
gboolean qof_commit_edit_part2(QofInstance *inst, void(*on_error)(QofInstance *, QofBackendError), void(*on_done)(QofInstance *), void(*on_free)(QofInstance *))
GncGUID * kvp_value_get_guid(const KvpValue *value)
const char * xaccAccountGetTaxUSCode(const Account *acc)
gboolean xaccAccountIsAPARType(GNCAccountType t)
void qof_collection_insert_entity(QofCollection *, QofInstance *)
void qof_collection_mark_clean(QofCollection *)
KvpValue * kvp_frame_get_slot_path(KvpFrame *frame, const gchar *first_key,...)
gboolean xaccAccountStringToType(const char *str, GNCAccountType *type)
void xaccTransCommitEdit(Transaction *trans)
Additional event handling code.
void xaccAccountSetReconcilePostponeBalance(Account *acc, gnc_numeric balance)
gboolean xaccAccountEqual(const Account *aa, const Account *ab, gboolean check_guids)
gboolean xaccAccountGetTaxRelated(const Account *acc)
void gnc_account_set_start_cleared_balance(Account *acc, const gnc_numeric start_baln)
Account * xaccCloneAccount(const Account *from, QofBook *book)
void xaccTransBeginEdit(Transaction *trans)
gnc_numeric xaccAccountGetReconciledBalance(const Account *acc)
gchar * kvp_frame_to_string(const KvpFrame *frame)
gint gnc_account_n_children(const Account *account)
void gnc_account_join_children(Account *to_parent, Account *from_parent)
gnc_numeric xaccAccountGetBalanceAsOfDate(Account *acc, time64 date)
KvpFrame * kvp_frame_set_value_nc(KvpFrame *frame, const gchar *path, KvpValue *value)
gnc_numeric xaccAccountGetBalance(const Account *acc)
gboolean xaccAccountGetReconcileLastDate(const Account *acc, time64 *last_date)
void dxaccAccountSetQuoteTZ(Account *acc, const char *tz)
void xaccAccountSetCommoditySCU(Account *acc, int scu)
gboolean qof_instance_books_equal(gconstpointer ptr1, gconstpointer ptr2)
gnc_commodity * gnc_account_get_currency_or_parent(const Account *account)
gboolean xaccAccountGetHidden(const Account *acc)
gint64 xaccAccountCountSplits(const Account *acc, gboolean include_children)
gnc_numeric gnc_numeric_sub(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
gboolean gnc_account_insert_split(Account *acc, Split *s)
GList * gnc_account_get_descendants(const Account *account)
void xaccAccountSetTaxUSCode(Account *acc, const char *code)
guint32 xaccParentAccountTypesCompatibleWith(GNCAccountType type)
gboolean xaccAccountGetReconcileChildrenStatus(const Account *acc)
gboolean xaccAccountGetReconcileLastInterval(const Account *acc, int *months, int *days)
void kvp_frame_for_each_slot(KvpFrame *f, void(*proc)(const gchar *key, KvpValue *value, gpointer data), gpointer data)
const char * dxaccAccountGetPriceSrc(const Account *acc)
gboolean gnc_lot_is_closed(GNCLot *lot)
GList * gnc_account_get_children(const Account *account)
void xaccAccountSetHidden(Account *acc, gboolean val)
void xaccAccountBeginEdit(Account *acc)
gboolean xaccAccountHasAncestor(const Account *acc, const Account *ancestor)
Account * xaccSplitGetAccount(const Split *s)
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
gint qof_instance_guid_compare(const gconstpointer ptr1, const gconstpointer ptr2)
gboolean xaccAccountGetPlaceholder(const Account *acc)
gint gnc_account_get_current_depth(const Account *account)
struct KvpFrameImpl KvpFrame
#define LEAVE(format, args...)
void(* QofSetterFunc)(gpointer, gpointer)
Account * xaccAccountGainsAccount(Account *acc, gnc_commodity *curr)
const char * gnc_commodity_get_unique_name(const gnc_commodity *cm)
Account * gnc_account_nth_child(const Account *parent, gint num)
Account * xaccMallocAccount(QofBook *book)
gint gnc_account_child_index(const Account *parent, const Account *child)
void xaccAccountSetAutoInterestXfer(Account *acc, gboolean option)
KvpFrame * kvp_value_get_frame(const KvpValue *value)
QofCollection * qof_book_get_collection(const QofBook *, QofIdType)
void xaccAccountSetTaxUSPayerNameSource(Account *acc, const char *source)
gnc_numeric gnc_pricedb_convert_balance_nearest_price(GNCPriceDB *pdb, gnc_numeric balance, const gnc_commodity *balance_currency, const gnc_commodity *new_currency, Timespec t)
Account * gnc_lot_get_account(const GNCLot *lot)
gboolean qof_object_register(const QofObject *object)
void xaccAccountSetDescription(Account *acc, const char *str)
void DxaccAccountSetCurrency(Account *acc, gnc_commodity *currency)
gpointer qof_collection_get_data(const QofCollection *col)
void gnc_account_set_start_balance(Account *acc, const gnc_numeric start_baln)
void xaccAccountSetNonStdSCU(Account *acc, gboolean flag)
void kvp_value_delete(KvpValue *value)
LotList * xaccAccountFindOpenLots(const Account *acc, gboolean(*match_func)(GNCLot *lot, gpointer user_data), gpointer user_data, GCompareFunc sort_func)
Account * gnc_account_get_root(Account *acc)
gboolean qof_book_shutting_down(const QofBook *book)
const char * xaccAccountGetName(const Account *acc)
void qof_event_gen(QofInstance *entity, QofEventId event_type, gpointer event_data)
Invoke all registered event handlers using the given arguments.
const char * xaccAccountGetTypeStr(GNCAccountType type)
#define GNC_EVENT_ITEM_ADDED
const char * xaccAccountGetSortOrder(const Account *acc)
GncImportMatchMap * gnc_account_create_imap(Account *acc)
API for Transactions and Splits (journal entries)
int xaccAccountStagedTransactionTraversal(const Account *acc, unsigned int stage, TransactionCallback thunk, void *cb_data)
void xaccAccountCommitEdit(Account *acc)
void xaccClearMark(Account *acc, short val)
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
void xaccAccountSetName(Account *acc, const char *str)
gnc_commodity * gnc_commodity_obtain_twin(const gnc_commodity *from, QofBook *book)
gboolean xaccAccountGetAutoInterestXfer(const Account *acc, gboolean default_value)
GNCPolicy * gnc_account_get_policy(Account *acc)
gboolean gnc_commodity_equiv(const gnc_commodity *a, const gnc_commodity *b)
void gnc_account_merge_children(Account *parent)
gboolean xaccAccountIsEquityType(GNCAccountType t)
void xaccTransGetDatePostedTS(const Transaction *trans, Timespec *ts)
void xaccAccountSetReconcileChildrenStatus(Account *acc, gboolean status)
const gchar * QofLogModule
const gchar * gnc_get_account_separator_string(void)
void xaccAccountSetCommodity(Account *acc, gnc_commodity *com)
gnc_numeric xaccSplitGetAmount(const Split *split)
const char * xaccAccountGetNotes(const Account *acc)
gboolean xaccAccountGetReconcilePostponeBalance(const Account *acc, gnc_numeric *balance)
gint gnc_account_get_tree_depth(const Account *account)
GNCPolicy * xaccGetFIFOPolicy(void)
Account * xaccAccountLookup(const GncGUID *guid, QofBook *book)
void xaccAccountSetTaxUSCopyNumber(Account *acc, gint64 copy_number)