31 #include <glib/gi18n.h> 40 #include "TransactionP.hpp" 45 #include "qofinstance-p.h" 51 #include <unordered_set> 53 static QofLogModule log_module = GNC_MOD_ACCOUNT;
56 static gchar account_separator[8] =
".";
57 static gunichar account_uc_separator =
':';
59 static bool imap_convert_bayes_to_flat_run =
false;
62 static const std::string KEY_ASSOC_INCOME_ACCOUNT(
"ofx/associated-income-account");
63 static const std::string KEY_RECONCILE_INFO(
"reconcile-info");
64 static const std::string KEY_INCLUDE_CHILDREN(
"include-children");
65 static const std::string KEY_POSTPONE(
"postpone");
66 static const std::string KEY_LOT_MGMT(
"lot-mgmt");
67 static const std::string KEY_ONLINE_ID(
"online_id");
68 static const std::string KEY_IMP_APPEND_TEXT(
"import-append-text");
69 static const std::string AB_KEY(
"hbci");
70 static const std::string AB_ACCOUNT_ID(
"account-id");
71 static const std::string AB_ACCOUNT_UID(
"account-uid");
72 static const std::string AB_BANK_CODE(
"bank-code");
73 static const std::string AB_TRANS_RETRIEVAL(
"trans-retrieval");
75 static const std::string KEY_BALANCE_LIMIT(
"balance-limit");
76 static const std::string KEY_BALANCE_HIGHER_LIMIT_VALUE(
"higher-value");
77 static const std::string KEY_BALANCE_LOWER_LIMIT_VALUE(
"lower-value");
78 static const std::string KEY_BALANCE_INCLUDE_SUB_ACCTS(
"inlude-sub-accts");
80 using FinalProbabilityVec=std::vector<std::pair<std::string, int32_t>>;
81 using ProbabilityVec=std::vector<std::pair<std::string, struct AccountProbability>>;
82 using FlatKvpEntry=std::pair<std::string, KvpValue*>;
105 PROP_END_NOCLOSING_BALANCE,
106 PROP_END_CLEARED_BALANCE,
107 PROP_END_RECONCILED_BALANCE,
112 PROP_TAX_COPY_NUMBER,
123 PROP_IMP_APPEND_TEXT,
124 PROP_IS_OPENING_BALANCE,
125 PROP_OFX_INCOME_ACCOUNT,
129 PROP_AB_TRANS_RETRIEVAL,
137 PROP_START_NOCLOSING_BALANCE,
138 PROP_START_CLEARED_BALANCE,
139 PROP_START_RECONCILED_BALANCE,
142 #define GET_PRIVATE(o) \ 143 ((AccountPrivate*)gnc_account_get_instance_private((Account*)o)) 146 static const std::map<GNCAccountType, const char*> gnc_acct_debit_strs = {
163 static const char* dflt_acct_debit_str = N_(
"Debit");
166 static const std::map<GNCAccountType, const char*> gnc_acct_credit_strs = {
183 static const char* dflt_acct_credit_str = N_(
"Credit");
192 static void xaccAccountBringUpToDate (
Account *acc);
205 return account_separator;
209 gnc_get_account_separator (
void)
211 return account_uc_separator;
215 gnc_set_account_separator (
const gchar *separator)
220 uc = g_utf8_get_char_validated(separator, -1);
221 if ((uc == (gunichar) - 2) || (uc == (gunichar) - 1) || g_unichar_isalnum(uc))
223 account_uc_separator =
':';
224 strcpy(account_separator,
":");
228 account_uc_separator = uc;
229 count = g_unichar_to_utf8(uc, account_separator);
230 account_separator[count] =
'\0';
235 gchar *message =
nullptr;
237 if ( !invalid_account_names )
246 message = g_strdup_printf(
247 _(
"The separator character \"%s\" is used in one or more account names.\n\n" 248 "This will result in unexpected behaviour. " 249 "Either change the account names or choose another separator character.\n\n" 250 "Below you will find the list of invalid account names:\n" 251 "%s"), separator, account_list );
252 g_free ( account_list );
259 const gchar *separator;
263 check_acct_name (
Account *acct, gpointer user_data)
267 if (g_strstr_len (name, -1, cb->separator))
268 cb->list = g_list_prepend (cb->list, g_strdup (name));
273 g_return_val_if_fail (separator !=
nullptr,
nullptr);
274 if (!book)
return nullptr;
277 (AccountCb)check_acct_name, &cb);
284 static inline void mark_account (
Account *acc);
288 qof_instance_set_dirty(&acc->inst);
295 G_DEFINE_TYPE_WITH_PRIVATE(
Account, gnc_account, QOF_TYPE_INSTANCE)
302 priv = GET_PRIVATE(acc);
303 priv->parent =
nullptr;
304 priv->children =
nullptr;
315 priv->lots =
nullptr;
317 priv->commodity =
nullptr;
318 priv->commodity_scu = 0;
319 priv->non_standard_scu = FALSE;
321 priv->balance = gnc_numeric_zero();
322 priv->noclosing_balance = gnc_numeric_zero();
323 priv->cleared_balance = gnc_numeric_zero();
324 priv->reconciled_balance = gnc_numeric_zero();
325 priv->starting_balance = gnc_numeric_zero();
326 priv->starting_noclosing_balance = gnc_numeric_zero();
327 priv->starting_cleared_balance = gnc_numeric_zero();
328 priv->starting_reconciled_balance = gnc_numeric_zero();
329 priv->balance_dirty = FALSE;
331 priv->higher_balance_limit = {};
332 priv->lower_balance_limit = {};
333 priv->include_sub_account_balances = {};
335 new (&priv->splits) SplitsVec ();
336 priv->splits_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
337 priv->sort_dirty = FALSE;
341 gnc_account_dispose (GObject *acctp)
343 G_OBJECT_CLASS(gnc_account_parent_class)->dispose(acctp);
347 gnc_account_finalize(GObject* acctp)
349 G_OBJECT_CLASS(gnc_account_parent_class)->finalize(acctp);
359 gnc_account_get_property (GObject *
object,
367 g_return_if_fail(GNC_IS_ACCOUNT(
object));
369 account = GNC_ACCOUNT(
object);
370 priv = GET_PRIVATE(account);
374 g_value_set_string(value, priv->accountName);
380 g_value_set_string(value, priv->accountCode);
382 case PROP_DESCRIPTION:
383 g_value_set_string(value, priv->description);
393 g_value_set_int(value, priv->type);
396 g_value_take_object(value, priv->commodity);
398 case PROP_COMMODITY_SCU:
399 g_value_set_int(value, priv->commodity_scu);
401 case PROP_NON_STD_SCU:
402 g_value_set_boolean(value, priv->non_standard_scu);
404 case PROP_SORT_DIRTY:
405 g_value_set_boolean(value, priv->sort_dirty);
407 case PROP_BALANCE_DIRTY:
408 g_value_set_boolean(value, priv->balance_dirty);
410 case PROP_START_BALANCE:
411 g_value_set_boxed(value, &priv->starting_balance);
413 case PROP_START_NOCLOSING_BALANCE:
414 g_value_set_boxed(value, &priv->starting_noclosing_balance);
416 case PROP_START_CLEARED_BALANCE:
417 g_value_set_boxed(value, &priv->starting_cleared_balance);
419 case PROP_START_RECONCILED_BALANCE:
420 g_value_set_boxed(value, &priv->starting_reconciled_balance);
422 case PROP_END_BALANCE:
423 g_value_set_boxed(value, &priv->balance);
425 case PROP_END_NOCLOSING_BALANCE:
426 g_value_set_boxed(value, &priv->noclosing_balance);
428 case PROP_END_CLEARED_BALANCE:
429 g_value_set_boxed(value, &priv->cleared_balance);
431 case PROP_END_RECONCILED_BALANCE:
432 g_value_set_boxed(value, &priv->reconciled_balance);
436 g_value_set_pointer(value, priv->policy);
439 g_value_set_int(value, priv->mark);
441 case PROP_TAX_RELATED:
447 case PROP_TAX_SOURCE:
448 g_value_set_string(value,
451 case PROP_TAX_COPY_NUMBER:
452 g_value_set_int64(value,
458 case PROP_AUTO_INTEREST:
461 case PROP_IS_OPENING_BALANCE:
464 case PROP_PLACEHOLDER:
470 case PROP_SORT_ORDER:
473 case PROP_SORT_REVERSED:
476 case PROP_LOT_NEXT_ID:
478 g_value_set_int64 (value, 0);
479 qof_instance_get_path_kvp (QOF_INSTANCE (account), value, {KEY_LOT_MGMT,
"next-id"});
481 case PROP_ONLINE_ACCOUNT:
482 qof_instance_get_path_kvp (QOF_INSTANCE (account), value, {KEY_ONLINE_ID});
484 case PROP_IMP_APPEND_TEXT:
487 case PROP_OFX_INCOME_ACCOUNT:
488 qof_instance_get_path_kvp (QOF_INSTANCE (account), value, {KEY_ASSOC_INCOME_ACCOUNT});
490 case PROP_AB_ACCOUNT_ID:
491 qof_instance_get_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_ACCOUNT_ID});
493 case PROP_AB_ACCOUNT_UID:
494 qof_instance_get_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_ACCOUNT_UID});
496 case PROP_AB_BANK_CODE:
497 qof_instance_get_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_BANK_CODE});
499 case PROP_AB_TRANS_RETRIEVAL:
500 qof_instance_get_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_TRANS_RETRIEVAL});
503 G_OBJECT_WARN_INVALID_PROPERTY_ID(
object, prop_id, pspec);
509 gnc_account_set_property (GObject *
object,
516 g_return_if_fail(GNC_IS_ACCOUNT(
object));
517 account = GNC_ACCOUNT(
object);
518 if (prop_id < PROP_RUNTIME_0)
519 g_assert (qof_instance_get_editlevel(account));
529 case PROP_DESCRIPTION:
545 case PROP_COMMODITY_SCU:
548 case PROP_NON_STD_SCU:
551 case PROP_SORT_DIRTY:
554 case PROP_BALANCE_DIRTY:
557 case PROP_START_BALANCE:
558 number =
static_cast<gnc_numeric*
>(g_value_get_boxed(value));
561 case PROP_START_CLEARED_BALANCE:
562 number =
static_cast<gnc_numeric*
>(g_value_get_boxed(value));
565 case PROP_START_RECONCILED_BALANCE:
566 number =
static_cast<gnc_numeric*
>(g_value_get_boxed(value));
575 case PROP_TAX_RELATED:
581 case PROP_TAX_SOURCE:
583 g_value_get_string(value));
585 case PROP_TAX_COPY_NUMBER:
587 g_value_get_int64(value));
592 case PROP_AUTO_INTEREST:
595 case PROP_IS_OPENING_BALANCE:
598 case PROP_PLACEHOLDER:
604 case PROP_SORT_ORDER:
607 case PROP_SORT_REVERSED:
610 case PROP_LOT_NEXT_ID:
611 qof_instance_set_path_kvp (QOF_INSTANCE (account), value, {KEY_LOT_MGMT,
"next-id"});
613 case PROP_ONLINE_ACCOUNT:
614 qof_instance_set_path_kvp (QOF_INSTANCE (account), value, {KEY_ONLINE_ID});
616 case PROP_IMP_APPEND_TEXT:
619 case PROP_OFX_INCOME_ACCOUNT:
620 qof_instance_set_path_kvp (QOF_INSTANCE (account), value, {KEY_ASSOC_INCOME_ACCOUNT});
622 case PROP_AB_ACCOUNT_ID:
623 qof_instance_set_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_ACCOUNT_ID});
625 case PROP_AB_ACCOUNT_UID:
626 qof_instance_set_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_ACCOUNT_UID});
628 case PROP_AB_BANK_CODE:
629 qof_instance_set_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_BANK_CODE});
631 case PROP_AB_TRANS_RETRIEVAL:
632 qof_instance_set_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_TRANS_RETRIEVAL});
635 G_OBJECT_WARN_INVALID_PROPERTY_ID(
object, prop_id, pspec);
643 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
645 gobject_class->dispose = gnc_account_dispose;
646 gobject_class->finalize = gnc_account_finalize;
647 gobject_class->set_property = gnc_account_set_property;
648 gobject_class->get_property = gnc_account_get_property;
650 g_object_class_install_property
653 g_param_spec_string (
"name",
655 "The accountName is an arbitrary string " 656 "assigned by the user. It is intended to " 657 "a short, 5 to 30 character long string " 658 "that is displayed by the GUI as the " 659 "account mnemonic. Account names may be " 660 "repeated. but no two accounts that share " 661 "a parent may have the same name.",
663 static_cast<GParamFlags>(G_PARAM_READWRITE)));
665 g_object_class_install_property
668 g_param_spec_string (
"fullname",
670 "The name of the account concatenated with " 671 "all its parent account names to indicate " 674 static_cast<GParamFlags>(G_PARAM_READABLE)));
676 g_object_class_install_property
679 g_param_spec_string (
"code",
681 "The account code is an arbitrary string " 682 "assigned by the user. It is intended to " 683 "be reporting code that is a synonym for " 686 static_cast<GParamFlags>(G_PARAM_READWRITE)));
688 g_object_class_install_property
691 g_param_spec_string (
"description",
692 "Account Description",
693 "The account description is an arbitrary " 694 "string assigned by the user. It is intended " 695 "to be a longer, 1-5 sentence description of " 696 "what this account is all about.",
698 static_cast<GParamFlags>(G_PARAM_READWRITE)));
700 g_object_class_install_property
703 g_param_spec_string (
"color",
705 "The account color is a color string assigned " 706 "by the user. It is intended to highlight the " 707 "account based on the users wishes.",
709 static_cast<GParamFlags>(G_PARAM_READWRITE)));
711 g_object_class_install_property
714 g_param_spec_string (
"notes",
716 "The account notes is an arbitrary provided " 717 "for the user to attach any other text that " 718 "they would like to associate with the account.",
720 static_cast<GParamFlags>(G_PARAM_READWRITE)));
722 g_object_class_install_property
725 g_param_spec_int (
"type",
727 "The account type, picked from the enumerated list " 728 "that includes ACCT_TYPE_BANK, ACCT_TYPE_STOCK, " 729 "ACCT_TYPE_CREDIT, ACCT_TYPE_INCOME, etc.",
733 static_cast<GParamFlags>(G_PARAM_READWRITE)));
735 g_object_class_install_property
738 g_param_spec_object (
"commodity",
740 "The commodity field denotes the kind of " 741 "'stuff' stored in this account, whether " 742 "it is USD, gold, stock, etc.",
744 static_cast<GParamFlags>(G_PARAM_READWRITE)));
746 g_object_class_install_property
749 g_param_spec_int (
"commodity-scu",
751 "The smallest fraction of the commodity that is " 752 "tracked. This number is used as the denominator " 753 "value in 1/x, so a value of 100 says that the " 754 "commodity can be divided into hundredths. E.G." 755 "1 USD can be divided into 100 cents.",
759 static_cast<GParamFlags>(G_PARAM_READWRITE)));
761 g_object_class_install_property
764 g_param_spec_boolean (
"non-std-scu",
766 "TRUE if the account SCU doesn't match " 767 "the commodity SCU. This indicates a case " 768 "where the two were accidentally set to " 769 "mismatched values in older versions of " 772 static_cast<GParamFlags>(G_PARAM_READWRITE)));
774 g_object_class_install_property
777 g_param_spec_boolean(
"sort-dirty",
779 "TRUE if the splits in the account needs to be " 780 "resorted. This flag is set by the accounts " 781 "code for certain internal modifications, or " 782 "when external code calls the engine to say a " 783 "split has been modified in a way that may " 784 "affect the sort order of the account. Note: " 785 "This value can only be set to TRUE.",
787 static_cast<GParamFlags>(G_PARAM_READWRITE)));
789 g_object_class_install_property
792 g_param_spec_boolean(
"balance-dirty",
794 "TRUE if the running balances in the account " 795 "needs to be recalculated. This flag is set " 796 "by the accounts code for certain internal " 797 "modifications, or when external code calls " 798 "the engine to say a split has been modified. " 799 "Note: This value can only be set to TRUE.",
801 static_cast<GParamFlags>(G_PARAM_READWRITE)));
803 g_object_class_install_property
806 g_param_spec_boxed(
"start-balance",
808 "The starting balance for the account. This " 809 "parameter is intended for use with backends that " 810 "do not return the complete list of splits for an " 811 "account, but rather return a partial list. In " 812 "such a case, the backend will typically return " 813 "all of the splits after some certain date, and " 814 "the 'starting balance' will represent the " 815 "summation of the splits up to that date.",
817 static_cast<GParamFlags>(G_PARAM_READWRITE)));
819 g_object_class_install_property
821 PROP_START_NOCLOSING_BALANCE,
822 g_param_spec_boxed(
"start-noclosing-balance",
823 "Starting No-closing Balance",
824 "The starting balance for the account, ignoring closing." 825 "This parameter is intended for use with backends " 826 "that do not return the complete list of splits " 827 "for an account, but rather return a partial " 828 "list. In such a case, the backend will " 829 "typically return all of the splits after " 830 "some certain date, and the 'starting noclosing " 831 "balance' will represent the summation of the " 832 "splits up to that date, ignoring closing splits.",
834 static_cast<GParamFlags>(G_PARAM_READWRITE)));
836 g_object_class_install_property
838 PROP_START_CLEARED_BALANCE,
839 g_param_spec_boxed(
"start-cleared-balance",
840 "Starting Cleared Balance",
841 "The starting cleared balance for the account. " 842 "This parameter is intended for use with backends " 843 "that do not return the complete list of splits " 844 "for an account, but rather return a partial " 845 "list. In such a case, the backend will " 846 "typically return all of the splits after " 847 "some certain date, and the 'starting cleared " 848 "balance' will represent the summation of the " 849 "splits up to that date.",
851 static_cast<GParamFlags>(G_PARAM_READWRITE)));
853 g_object_class_install_property
855 PROP_START_RECONCILED_BALANCE,
856 g_param_spec_boxed(
"start-reconciled-balance",
857 "Starting Reconciled Balance",
858 "The starting reconciled balance for the " 859 "account. This parameter is intended for use " 860 "with backends that do not return the complete " 861 "list of splits for an account, but rather return " 862 "a partial list. In such a case, the backend " 863 "will typically return all of the splits after " 864 "some certain date, and the 'starting reconciled " 865 "balance' will represent the summation of the " 866 "splits up to that date.",
868 static_cast<GParamFlags>(G_PARAM_READWRITE)));
870 g_object_class_install_property
873 g_param_spec_boxed(
"end-balance",
874 "Ending Account Balance",
875 "This is the current ending balance for the " 876 "account. It is computed from the sum of the " 877 "starting balance and all splits in the account.",
881 g_object_class_install_property
883 PROP_END_NOCLOSING_BALANCE,
884 g_param_spec_boxed(
"end-noclosing-balance",
885 "Ending Account Noclosing Balance",
886 "This is the current ending no-closing balance for " 887 "the account. It is computed from the sum of the " 888 "starting balance and all cleared splits in the " 893 g_object_class_install_property
895 PROP_END_CLEARED_BALANCE,
896 g_param_spec_boxed(
"end-cleared-balance",
897 "Ending Account Cleared Balance",
898 "This is the current ending cleared balance for " 899 "the account. It is computed from the sum of the " 900 "starting balance and all cleared splits in the " 905 g_object_class_install_property
907 PROP_END_RECONCILED_BALANCE,
908 g_param_spec_boxed(
"end-reconciled-balance",
909 "Ending Account Reconciled Balance",
910 "This is the current ending reconciled balance " 911 "for the account. It is computed from the sum of " 912 "the starting balance and all reconciled splits " 915 static_cast<GParamFlags>(G_PARAM_READABLE)));
917 g_object_class_install_property
920 g_param_spec_pointer (
"policy",
922 "The account lots policy.",
923 static_cast<GParamFlags>(G_PARAM_READWRITE)));
925 g_object_class_install_property
928 g_param_spec_int (
"acct-mark",
934 static_cast<GParamFlags>(G_PARAM_READWRITE)));
936 g_object_class_install_property
939 g_param_spec_boolean (
"tax-related",
941 "Whether the account maps to an entry on an " 942 "income tax document.",
944 static_cast<GParamFlags>(G_PARAM_READWRITE)));
946 g_object_class_install_property
948 PROP_IS_OPENING_BALANCE,
949 g_param_spec_boolean (
"opening-balance",
951 "Whether the account holds opening balances",
953 static_cast<GParamFlags>(G_PARAM_READWRITE)));
955 g_object_class_install_property
958 g_param_spec_string (
"tax-code",
960 "This is the code for mapping an account to a " 961 "specific entry on a taxable document. In the " 962 "United States it is used to transfer totals " 963 "into tax preparation software.",
965 static_cast<GParamFlags>(G_PARAM_READWRITE)));
967 g_object_class_install_property
970 g_param_spec_string (
"tax-source",
972 "This specifies where exported name comes from.",
974 static_cast<GParamFlags>(G_PARAM_READWRITE)));
976 g_object_class_install_property
978 PROP_TAX_COPY_NUMBER,
979 g_param_spec_int64 (
"tax-copy-number",
981 "This specifies the copy number of the tax " 986 static_cast<GParamFlags>(G_PARAM_READWRITE)));
988 g_object_class_install_property
991 g_param_spec_boolean (
"hidden",
993 "Whether the account should be hidden in the " 996 static_cast<GParamFlags>(G_PARAM_READWRITE)));
998 g_object_class_install_property
1001 g_param_spec_boolean (
"auto-interest-transfer",
1003 "Whether an interest transfer should be automatically " 1004 "added before reconcile.",
1006 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1008 g_object_class_install_property
1011 g_param_spec_boolean (
"placeholder",
1013 "Whether the account is a placeholder account which does not " 1014 "allow transactions to be created, edited or deleted.",
1016 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1018 g_object_class_install_property
1021 g_param_spec_string (
"filter",
1023 "The account filter is a value saved to allow " 1024 "filters to be recalled.",
1026 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1028 g_object_class_install_property
1031 g_param_spec_string (
"sort-order",
1032 "Account Sort Order",
1033 "The account sort order is a value saved to allow " 1034 "the sort order to be recalled.",
1036 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1038 g_object_class_install_property
1041 g_param_spec_boolean (
"sort-reversed",
1042 "Account Sort Reversed",
1043 "Parameter to store whether the sort order is reversed or not.",
1045 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1047 g_object_class_install_property
1050 g_param_spec_int64 (
"lot-next-id",
1052 "Tracks the next id to use in gnc_lot_make_default.",
1056 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1058 g_object_class_install_property
1060 PROP_ONLINE_ACCOUNT,
1061 g_param_spec_string (
"online-id",
1062 "Online Account ID",
1063 "The online account which corresponds to this " 1064 "account for OFX import",
1066 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1068 g_object_class_install_property
1070 PROP_IMP_APPEND_TEXT,
1071 g_param_spec_boolean (
"import-append-text",
1072 "Import Append Text",
1073 "Saved state of Append checkbox for setting initial " 1074 "value next time this account is imported.",
1076 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1078 g_object_class_install_property(
1080 PROP_OFX_INCOME_ACCOUNT,
1081 g_param_spec_boxed(
"ofx-income-account",
1082 "Associated income account",
1083 "Used by the OFX importer.",
1085 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1087 g_object_class_install_property
1090 g_param_spec_string (
"ab-account-id",
1091 "AQBanking Account ID",
1092 "The AqBanking account which corresponds to this " 1093 "account for AQBanking import",
1095 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1096 g_object_class_install_property
1099 g_param_spec_string (
"ab-bank-code",
1100 "AQBanking Bank Code",
1101 "The online account which corresponds to this " 1102 "account for AQBanking import",
1104 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1106 g_object_class_install_property
1108 PROP_AB_ACCOUNT_UID,
1109 g_param_spec_int64 (
"ab-account-uid",
1110 "AQBanking Account UID",
1111 "Tracks the next id to use in gnc_lot_make_default.",
1115 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1117 g_object_class_install_property
1119 PROP_AB_TRANS_RETRIEVAL,
1120 g_param_spec_boxed(
"ab-trans-retrieval",
1121 "AQBanking Last Transaction Retrieval",
1122 "The time of the last transaction retrieval for this " 1125 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1130 xaccInitAccount (
Account * acc, QofBook *book)
1132 ENTER (
"book=%p\n", book);
1135 LEAVE (
"account=%p\n", acc);
1142 gnc_account_foreach_split (
const Account *acc, std::function<
void(Split*)> func,
1145 if (!GNC_IS_ACCOUNT (acc))
1148 auto splits{GET_PRIVATE(acc)->splits};
1150 std::for_each(splits.rbegin(), splits.rend(), func);
1152 std::for_each(splits.begin(), splits.end(), func);
1156 gnc_account_foreach_split_until_date (
const Account *acc,
time64 end_date,
1157 std::function<
void(Split*)> f)
1159 if (!GNC_IS_ACCOUNT (acc))
1162 auto after_date = [](
time64 end_date,
auto s) ->
bool 1165 auto splits{GET_PRIVATE(acc)->splits};
1166 auto after_date_iter = std::upper_bound (splits.begin(), splits.end(), end_date, after_date);
1167 std::for_each (splits.begin(), after_date_iter, f);
1175 if (!GNC_IS_ACCOUNT (acc))
1178 auto splits{GET_PRIVATE(acc)->splits};
1181 auto latest = std::find_if(splits.rbegin(), splits.rend(), predicate);
1182 return (latest == splits.rend()) ?
nullptr : *latest;
1186 auto earliest = std::find_if(splits.begin(), splits.end(), predicate);
1187 return (earliest == splits.end()) ?
nullptr : *earliest;
1195 gnc_account_get_book(
const Account *account)
1197 if (!account)
return nullptr;
1205 gnc_coll_get_root_account (QofCollection *col)
1207 if (!col)
return nullptr;
1212 gnc_coll_set_root_account (QofCollection *col,
Account *root)
1218 old_root = gnc_coll_get_root_account (col);
1219 if (old_root == root)
return;
1224 rpriv = GET_PRIVATE(root);
1232 qof_collection_set_data (col, root);
1242 gnc_book_get_root_account (QofBook *book)
1247 if (!book)
return nullptr;
1249 root = gnc_coll_get_root_account (col);
1256 gnc_book_set_root_account (QofBook *book,
Account *root)
1261 if (root && gnc_account_get_book(root) != book)
1263 PERR (
"cannot mix and match books freely!");
1268 gnc_coll_set_root_account (col, root);
1279 g_return_val_if_fail (book,
nullptr);
1281 acc =
static_cast<Account*
>(g_object_new (GNC_TYPE_ACCOUNT,
nullptr));
1282 xaccInitAccount (acc, book);
1295 rpriv = GET_PRIVATE(root);
1299 mark_account (root);
1301 gnc_book_set_root_account(book, root);
1311 g_return_val_if_fail(GNC_IS_ACCOUNT(from),
nullptr);
1312 g_return_val_if_fail(QOF_IS_BOOK(book),
nullptr);
1315 ret =
static_cast<Account*
>(g_object_new (GNC_TYPE_ACCOUNT,
nullptr));
1316 g_return_val_if_fail (ret,
nullptr);
1318 from_priv = GET_PRIVATE(from);
1319 priv = GET_PRIVATE(ret);
1320 xaccInitAccount (ret, book);
1325 priv->type = from_priv->type;
1331 qof_instance_copy_kvp (QOF_INSTANCE (ret), QOF_INSTANCE (from));
1338 priv->commodity_scu = from_priv->commodity_scu;
1339 priv->non_standard_scu = from_priv->non_standard_scu;
1341 qof_instance_set_dirty(&ret->inst);
1350 xaccFreeOneChildAccount (
Account *acc, gpointer dummy)
1354 if (qof_instance_get_editlevel(acc) == 0)
1360 xaccFreeAccountChildren (
Account *acc)
1366 priv = GET_PRIVATE(acc);
1367 children = g_list_copy(priv->children);
1368 g_list_foreach(children, (GFunc)xaccFreeOneChildAccount,
nullptr);
1369 g_list_free(children);
1373 g_list_free(priv->children);
1374 priv->children =
nullptr;
1382 xaccFreeAccount (
Account *acc)
1387 g_return_if_fail(GNC_IS_ACCOUNT(acc));
1389 priv = GET_PRIVATE(acc);
1396 qof_instance_set_destroying(acc, TRUE);
1400 PERR (
" instead of calling xaccFreeAccount(), please call\n" 1401 " xaccAccountBeginEdit(); xaccAccountDestroy();\n");
1404 xaccFreeAccountChildren(acc);
1410 PERR (
" instead of calling xaccFreeAccount(), please call\n" 1411 " xaccAccountBeginEdit(); xaccAccountDestroy();\n");
1413 for (lp = priv->lots; lp; lp = lp->next)
1415 GNCLot *lot =
static_cast<GNCLot*
>(lp->data);
1416 gnc_lot_destroy (lot);
1418 g_list_free (priv->lots);
1419 priv->lots =
nullptr;
1426 if (!priv->splits.empty())
1428 PERR (
" instead of calling xaccFreeAccount(), please call\n" 1429 " xaccAccountBeginEdit(); xaccAccountDestroy();\n");
1431 qof_instance_reset_editlevel(acc);
1433 for (
auto s : priv->splits)
1446 priv->accountName = priv->accountCode = priv->description =
nullptr;
1451 priv->last_num =
nullptr;
1452 priv->tax_us_code =
nullptr;
1453 priv->tax_us_pns =
nullptr;
1454 priv->color =
nullptr;
1455 priv->sort_order =
nullptr;
1456 priv->notes =
nullptr;
1457 priv->filter =
nullptr;
1459 priv->parent =
nullptr;
1460 priv->children =
nullptr;
1462 priv->balance = gnc_numeric_zero();
1463 priv->noclosing_balance = gnc_numeric_zero();
1464 priv->cleared_balance = gnc_numeric_zero();
1465 priv->reconciled_balance = gnc_numeric_zero();
1469 priv->commodity =
nullptr;
1471 priv->balance_dirty = FALSE;
1472 priv->sort_dirty = FALSE;
1473 priv->splits.~SplitsVec();
1474 g_hash_table_destroy (priv->splits_hash);
1477 g_object_unref(acc);
1487 g_return_if_fail(acc);
1499 PERR(
"commit error: %d", errcode);
1500 gnc_engine_signal_commit_error( errcode );
1508 priv = GET_PRIVATE(acc);
1511 xaccFreeAccount(acc);
1515 destroy_pending_splits_for_account(
QofInstance *ent, gpointer acc)
1517 Transaction *trans = (Transaction *) ent;
1521 while ((split = xaccTransFindSplitByAccount(trans, static_cast<Account*>(acc))))
1531 g_return_if_fail(acc);
1536 priv = GET_PRIVATE(acc);
1541 qof_instance_increase_editlevel(acc);
1544 xaccFreeAccountChildren(acc);
1546 PINFO (
"freeing splits for account %p (%s)",
1547 acc, priv->accountName ? priv->accountName :
"(null)");
1555 for (
auto s : priv->splits)
1560 priv->splits.clear();
1561 g_hash_table_remove_all (priv->splits_hash);
1578 for (
auto lp = priv->lots; lp; lp = lp->next)
1580 GNCLot *lot =
static_cast<GNCLot*
>(lp->data);
1581 gnc_lot_destroy (lot);
1584 g_list_free(priv->lots);
1585 priv->lots =
nullptr;
1587 qof_instance_set_dirty(&acc->inst);
1588 qof_instance_decrease_editlevel(acc);
1592 xaccAccountBringUpToDate(acc);
1601 g_return_if_fail(GNC_IS_ACCOUNT(acc));
1603 qof_instance_set_destroying(acc, TRUE);
1611 compare_account_by_name (gconstpointer a, gconstpointer b)
1614 if (a && !b)
return 1;
1615 if (b && !a)
return -1;
1616 if (!a && !b)
return 0;
1617 priv_a = GET_PRIVATE((
Account*)a);
1618 priv_b = GET_PRIVATE((
Account*)b);
1619 if ((priv_a->accountCode && strlen (priv_a->accountCode)) ||
1620 (priv_b->accountCode && strlen (priv_b->accountCode)))
1621 return g_strcmp0 (priv_a->accountCode, priv_b->accountCode);
1622 return g_strcmp0 (priv_a->accountName, priv_b->accountName);
1626 xaccAcctChildrenEqual(
const GList *na,
1628 gboolean check_guids)
1630 if ((!na && nb) || (na && !nb))
1632 PINFO (
"only one has accounts");
1635 if (g_list_length ((GList*)na) != g_list_length ((GList*)nb))
1637 PINFO (
"Accounts have different numbers of children");
1645 GList *node = g_list_find_custom ((GList*)nb, aa,
1646 (GCompareFunc)compare_account_by_name);
1650 PINFO (
"Unable to find matching child account.");
1653 ab =
static_cast<Account*
>(node->data);
1662 PWARN (
"accounts %s and %s differ", sa, sb);
1678 if (!aa && !ab)
return TRUE;
1680 g_return_val_if_fail(GNC_IS_ACCOUNT(aa), FALSE);
1681 g_return_val_if_fail(GNC_IS_ACCOUNT(ab), FALSE);
1683 priv_aa = GET_PRIVATE(aa);
1684 priv_ab = GET_PRIVATE(ab);
1685 if (priv_aa->type != priv_ab->type)
1687 PWARN (
"types differ: %d vs %d", priv_aa->type, priv_ab->type);
1691 if (g_strcmp0(priv_aa->accountName, priv_ab->accountName) != 0)
1693 PWARN (
"names differ: %s vs %s", priv_aa->accountName, priv_ab->accountName);
1697 if (g_strcmp0(priv_aa->accountCode, priv_ab->accountCode) != 0)
1699 PWARN (
"codes differ: %s vs %s", priv_aa->accountCode, priv_ab->accountCode);
1703 if (g_strcmp0(priv_aa->description, priv_ab->description) != 0)
1705 PWARN (
"descriptions differ: %s vs %s", priv_aa->description, priv_ab->description);
1711 PWARN (
"commodities differ");
1719 PWARN (
"GUIDs differ");
1724 if (qof_instance_compare_kvp (QOF_INSTANCE (aa), QOF_INSTANCE (ab)) != 0)
1729 frame_a = qof_instance_kvp_as_string (QOF_INSTANCE (aa));
1730 frame_b = qof_instance_kvp_as_string (QOF_INSTANCE (ab));
1732 PWARN (
"kvp frames differ:\n%s\n\nvs\n\n%s", frame_a, frame_b);
1748 PWARN (
"starting balances differ: %s vs %s", str_a, str_b);
1757 priv_ab->starting_noclosing_balance))
1765 PWARN (
"starting noclosing balances differ: %s vs %s", str_a, str_b);
1773 priv_ab->starting_cleared_balance))
1781 PWARN (
"starting cleared balances differ: %s vs %s", str_a, str_b);
1790 priv_ab->starting_reconciled_balance))
1798 PWARN (
"starting reconciled balances differ: %s vs %s", str_a, str_b);
1814 PWARN (
"balances differ: %s vs %s", str_a, str_b);
1830 PWARN (
"noclosing balances differ: %s vs %s", str_a, str_b);
1845 PWARN (
"cleared balances differ: %s vs %s", str_a, str_b);
1853 if (!
gnc_numeric_equal(priv_aa->reconciled_balance, priv_ab->reconciled_balance))
1861 PWARN (
"reconciled balances differ: %s vs %s", str_a, str_b);
1872 if (priv_aa->splits.size() != priv_ab->splits.size())
1874 PWARN (
"number of splits differs");
1878 for (
auto it_a = priv_aa->splits.begin(), it_b = priv_ab->splits.begin();
1879 it_a != priv_aa->splits.end() && it_b != priv_ab->splits.end();
1887 PWARN (
"splits differ");
1893 if (!xaccAcctChildrenEqual(priv_aa->children, priv_ab->children, check_guids))
1895 PWARN (
"children differ");
1909 g_return_if_fail(GNC_IS_ACCOUNT(acc));
1914 priv = GET_PRIVATE(acc);
1915 priv->sort_dirty = TRUE;
1923 g_return_if_fail(GNC_IS_ACCOUNT(acc));
1928 priv = GET_PRIVATE(acc);
1929 priv->balance_dirty = TRUE;
1936 g_return_if_fail (GNC_IS_ACCOUNT (acc));
1941 priv = GET_PRIVATE (acc);
1942 priv->defer_bal_computation = defer;
1950 priv = GET_PRIVATE (acc);
1951 return priv->defer_bal_computation;
1958 static bool split_cmp_less (
const Split* a,
const Split* b)
1968 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
1969 g_return_val_if_fail(GNC_IS_SPLIT(s), FALSE);
1971 priv = GET_PRIVATE(acc);
1972 if (!g_hash_table_add (priv->splits_hash, s))
1975 priv->splits.push_back (s);
1977 if (qof_instance_get_editlevel(acc) == 0)
1978 std::sort (priv->splits.begin(), priv->splits.end(), split_cmp_less);
1980 priv->sort_dirty =
true;
1987 priv->balance_dirty = TRUE;
1998 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
1999 g_return_val_if_fail(GNC_IS_SPLIT(s), FALSE);
2001 priv = GET_PRIVATE(acc);
2003 if (!g_hash_table_remove (priv->splits_hash, s))
2005 auto it = std::remove (priv->splits.begin(), priv->splits.end(), s);
2006 priv->splits.erase (it, priv->splits.end());
2012 priv->balance_dirty = TRUE;
2022 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2024 priv = GET_PRIVATE(acc);
2025 if (!priv->sort_dirty || (!force && qof_instance_get_editlevel(acc) > 0))
2027 std::sort (priv->splits.begin(), priv->splits.end(), split_cmp_less);
2028 priv->sort_dirty = FALSE;
2029 priv->balance_dirty = TRUE;
2033 xaccAccountBringUpToDate(
Account *acc)
2049 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2050 g_return_if_fail(guid);
2053 PINFO(
"acct=%p", acc);
2055 qof_instance_set_guid (&acc->inst, guid);
2056 qof_instance_set_dirty(&acc->inst);
2067 if (!guid || !book)
return nullptr;
2080 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2082 priv = GET_PRIVATE(acc);
2091 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2103 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2105 priv = GET_PRIVATE(acc);
2107 for (node = priv->children; node; node = node->next)
2119 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
2121 return GET_PRIVATE(acc)->policy;
2129 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2131 priv = GET_PRIVATE(acc);
2139 xaccAccountRemoveLot (
Account *acc, GNCLot *lot)
2143 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2144 g_return_if_fail(GNC_IS_LOT(lot));
2146 priv = GET_PRIVATE(acc);
2147 g_return_if_fail(priv->lots);
2149 ENTER (
"(acc=%p, lot=%p)", acc, lot);
2150 priv->lots = g_list_remove(priv->lots, lot);
2151 qof_event_gen (QOF_INSTANCE(lot), QOF_EVENT_REMOVE,
nullptr);
2153 LEAVE (
"(acc=%p, lot=%p)", acc, lot);
2164 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2165 g_return_if_fail(GNC_IS_LOT(lot));
2169 if (lot_account == acc)
2172 ENTER (
"(acc=%p, lot=%p)", acc, lot);
2177 old_acc = lot_account;
2178 opriv = GET_PRIVATE(old_acc);
2179 opriv->lots = g_list_remove(opriv->lots, lot);
2182 priv = GET_PRIVATE(acc);
2183 priv->lots = g_list_prepend(priv->lots, lot);
2184 gnc_lot_set_account(lot, acc);
2194 LEAVE (
"(acc=%p, lot=%p)", acc, lot);
2200 xaccPreSplitMove (Split *split)
2206 xaccPostSplitMove (Split *split,
Account *accto)
2210 xaccSplitSetAccount(split, accto);
2222 g_return_if_fail(GNC_IS_ACCOUNT(accfrom));
2223 g_return_if_fail(GNC_IS_ACCOUNT(accto));
2226 from_priv = GET_PRIVATE(accfrom);
2227 if (from_priv->splits.empty() || accfrom == accto)
2232 ENTER (
"(accfrom=%p, accto=%p)", accfrom, accto);
2237 std::for_each (from_priv->splits.begin(), from_priv->splits.end(), xaccPreSplitMove);
2254 auto splits = from_priv->splits;
2255 std::for_each (splits.begin(), splits.end(), [accto](
auto s){ xaccPostSplitMove (s, accto); });
2258 g_assert(from_priv->splits.empty());
2259 g_assert(from_priv->lots ==
nullptr);
2263 LEAVE (
"(accfrom=%p, accto=%p)", accfrom, accto);
2299 gnc_numeric balance;
2300 gnc_numeric noclosing_balance;
2301 gnc_numeric cleared_balance;
2302 gnc_numeric reconciled_balance;
2304 if (
nullptr == acc)
return;
2306 priv = GET_PRIVATE(acc);
2307 if (qof_instance_get_editlevel(acc) > 0)
return;
2308 if (!priv->balance_dirty || priv->defer_bal_computation)
return;
2312 balance = priv->starting_balance;
2313 noclosing_balance = priv->starting_noclosing_balance;
2314 cleared_balance = priv->starting_cleared_balance;
2315 reconciled_balance = priv->starting_reconciled_balance;
2317 PINFO (
"acct=%s starting baln=%" G_GINT64_FORMAT
"/%" G_GINT64_FORMAT,
2318 priv->accountName, balance.num, balance.denom);
2319 for (
auto split : priv->splits)
2323 balance = gnc_numeric_add_fixed(balance, amt);
2325 if (
NREC != split->reconciled)
2327 cleared_balance = gnc_numeric_add_fixed(cleared_balance, amt);
2330 if (
YREC == split->reconciled ||
2331 FREC == split->reconciled)
2333 reconciled_balance =
2334 gnc_numeric_add_fixed(reconciled_balance, amt);
2338 noclosing_balance = gnc_numeric_add_fixed(noclosing_balance, amt);
2340 split->balance = balance;
2341 split->noclosing_balance = noclosing_balance;
2342 split->cleared_balance = cleared_balance;
2343 split->reconciled_balance = reconciled_balance;
2347 priv->balance = balance;
2348 priv->noclosing_balance = noclosing_balance;
2349 priv->cleared_balance = cleared_balance;
2350 priv->reconciled_balance = reconciled_balance;
2351 priv->balance_dirty = FALSE;
2370 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
2378 const char *da, *db;
2381 if ( aa && !ab )
return -1;
2382 if ( !aa && ab )
return +1;
2383 if ( !aa && !ab )
return 0;
2385 priv_aa = GET_PRIVATE(aa);
2386 priv_ab = GET_PRIVATE(ab);
2389 da = priv_aa->accountCode;
2390 db = priv_ab->accountCode;
2393 result = g_strcmp0 (da, db);
2399 if (-1 == revorder[0])
2404 revorder [typeorder[i]] = i;
2413 if (ta < tb)
return -1;
2414 if (ta > tb)
return +1;
2417 da = priv_aa->accountName;
2418 db = priv_ab->accountName;
2442 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2446 priv = GET_PRIVATE(acc);
2447 if (priv->type == tip)
2452 priv->balance_dirty = TRUE;
2463 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2464 g_return_if_fail(str);
2467 priv = GET_PRIVATE(acc);
2468 if (g_strcmp0(str, priv->accountName) == 0)
2483 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2486 priv = GET_PRIVATE(acc);
2487 if (g_strcmp0(str, priv->accountCode) == 0)
2502 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2505 priv = GET_PRIVATE(acc);
2506 if (g_strcmp0(str, priv->description) == 0)
2516 set_kvp_string_path (
Account *acc, std::vector<std::string>
const & path,
2519 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2522 if (value && *value)
2524 GValue v = G_VALUE_INIT;
2525 g_value_init (&v, G_TYPE_STRING);
2526 g_value_set_static_string (&v, value);
2527 qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v, path);
2532 qof_instance_set_path_kvp (QOF_INSTANCE (acc),
nullptr, path);
2539 set_kvp_string_tag (
Account *acc,
const char *tag,
const char *value)
2541 set_kvp_string_path (acc, {tag}, value);
2545 get_kvp_string_path (
const Account *acc, std::vector<std::string>
const & path,
2549 if (acc ==
nullptr)
return nullptr;
2550 qof_instance_get_path_kvp (QOF_INSTANCE (acc), v, path);
2551 return G_VALUE_HOLDS_STRING (v) ? g_value_get_string (v) : nullptr;
2555 get_kvp_string_tag (
const Account *acc,
const char *tag, GValue *v)
2557 return get_kvp_string_path (acc, {tag}, v);
2563 set_kvp_string_tag (acc,
"color", str);
2569 set_kvp_string_tag (acc,
"filter", str);
2575 set_kvp_string_tag (acc,
"sort-order", str);
2581 set_kvp_string_tag (acc,
"sort-reversed", sortreversed ?
"true" :
nullptr);
2589 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2590 g_return_if_fail(GNC_IS_ACCOUNT(parent));
2592 parent_acc = GNC_ACCOUNT(parent);
2596 mark_account (parent_acc);
2605 set_kvp_string_tag (acc,
"notes", str);
2612 g_return_if_fail (GNC_IS_ACCOUNT(acc));
2613 g_return_if_fail (tag && *tag);
2615 std::vector<std::string> path = {
"associated-account", tag };
2621 if (GNC_IS_ACCOUNT(assoc_acct))
2623 GValue v = G_VALUE_INIT;
2624 g_value_init (&v, GNC_TYPE_GUID);
2626 qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v, path);
2630 qof_instance_set_path_kvp (QOF_INSTANCE (acc),
nullptr, path);
2642 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2643 g_return_if_fail(GNC_IS_COMMODITY(com));
2646 priv = GET_PRIVATE(acc);
2647 if (com == priv->commodity)
2652 priv->commodity = com;
2655 priv->non_standard_scu = FALSE;
2658 for (
auto s : priv->splits)
2667 priv->sort_dirty = TRUE;
2668 priv->balance_dirty = TRUE;
2685 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2687 priv = GET_PRIVATE(acc);
2689 priv->commodity_scu = scu;
2691 priv->non_standard_scu = TRUE;
2699 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0);
2700 return GET_PRIVATE(acc)->commodity_scu;
2708 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0);
2710 priv = GET_PRIVATE(acc);
2711 if (priv->non_standard_scu || !priv->commodity)
2712 return priv->commodity_scu;
2721 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2723 priv = GET_PRIVATE(acc);
2724 if (priv->non_standard_scu == flag)
2727 priv->non_standard_scu = flag;
2735 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0);
2736 return GET_PRIVATE(acc)->non_standard_scu;
2747 GValue v = G_VALUE_INIT;
2749 gnc_commodity *commodity;
2750 gnc_commodity_table *
table;
2752 if ((!acc) || (!currency))
return;
2753 g_value_init (&v, G_TYPE_STRING);
2754 g_value_set_static_string (&v, s);
2755 qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v, {
"old-currency"});
2761 commodity = gnc_commodity_table_lookup_unique (
table, s);
2775 account_foreach_descendant (
const Account *acc, AccountCb thunk,
2776 void* user_data,
bool sort)
2780 g_return_if_fail (GNC_IS_ACCOUNT(acc));
2781 g_return_if_fail (thunk);
2783 auto priv{GET_PRIVATE(acc)};
2786 children = g_list_copy (priv->children);
2790 children = priv->children;
2792 for (
auto node = children; node; node = node->next)
2794 auto child =
static_cast<Account*
>(node->data);
2795 thunk (child, user_data);
2796 account_foreach_descendant (child, thunk, user_data, sort);
2800 g_list_free (children);
2811 g_assert(GNC_IS_ACCOUNT(new_parent));
2812 g_assert(GNC_IS_ACCOUNT(child));
2815 ppriv = GET_PRIVATE(new_parent);
2816 cpriv = GET_PRIVATE(child);
2817 old_parent = cpriv->parent;
2818 if (old_parent == new_parent)
2840 PWARN (
"reparenting accounts across books is not correctly supported\n");
2849 cpriv->parent = new_parent;
2850 ppriv->children = g_list_append(ppriv->children, child);
2851 qof_instance_set_dirty(&new_parent->inst);
2852 qof_instance_set_dirty(&child->inst);
2875 if (!parent)
return;
2877 ppriv = GET_PRIVATE(parent);
2878 cpriv = GET_PRIVATE(child);
2880 if (cpriv->parent != parent)
2882 PERR (
"account not a child of parent");
2888 ed.idx = g_list_index(ppriv->children, child);
2890 ppriv->children = g_list_remove(ppriv->children, child);
2896 cpriv->parent =
nullptr;
2904 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
2905 return GET_PRIVATE(acc)->parent;
2913 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
2915 priv = GET_PRIVATE(acc);
2916 while (priv->parent)
2919 priv = GET_PRIVATE(acc);
2928 g_return_val_if_fail(GNC_IS_ACCOUNT(account), FALSE);
2929 return (GET_PRIVATE(account)->parent ==
nullptr);
2935 g_return_val_if_fail(GNC_IS_ACCOUNT(account),
nullptr);
2936 return g_list_copy(GET_PRIVATE(account)->children);
2945 g_return_val_if_fail(GNC_IS_ACCOUNT(account),
nullptr);
2948 priv = GET_PRIVATE(account);
2949 if (!priv->children)
2951 return g_list_sort(g_list_copy(priv->children), (GCompareFunc)
xaccAccountOrder);
2957 g_return_val_if_fail(GNC_IS_ACCOUNT(account), 0);
2958 return g_list_length(GET_PRIVATE(account)->children);
2964 g_return_val_if_fail(GNC_IS_ACCOUNT(parent), -1);
2965 g_return_val_if_fail(GNC_IS_ACCOUNT(child), -1);
2966 return g_list_index(GET_PRIVATE(parent)->children, child);
2972 g_return_val_if_fail(GNC_IS_ACCOUNT(parent),
nullptr);
2973 return static_cast<Account*
>(g_list_nth_data(GET_PRIVATE(parent)->children, num));
2977 count_acct (
Account *account, gpointer user_data)
2979 auto count {
static_cast<int*
>(user_data)};
2987 account_foreach_descendant (account, count_acct, &count, FALSE);
2997 g_return_val_if_fail(GNC_IS_ACCOUNT(account), 0);
2999 priv = GET_PRIVATE(account);
3002 account = priv->parent;
3003 priv = GET_PRIVATE(account);
3015 gint depth = 0, child_depth;
3017 g_return_val_if_fail(GNC_IS_ACCOUNT(account), 0);
3019 priv = GET_PRIVATE(account);
3020 if (!priv->children)
3023 for (node = priv->children; node; node = g_list_next(node))
3026 depth = MAX(depth, child_depth);
3032 collect_acct (
Account *account, gpointer user_data)
3034 auto listptr{
static_cast<GList**
>(user_data)};
3035 *listptr = g_list_prepend (*listptr, account);
3041 GList* list =
nullptr;
3042 account_foreach_descendant (account, collect_acct, &list, FALSE);
3043 return g_list_reverse (list);
3049 GList* list =
nullptr;
3050 account_foreach_descendant (account, collect_acct, &list, TRUE);
3051 return g_list_reverse (list);
3060 account_foreach_descendant_breadthfirst_until (
const Account *acc,
3064 gpointer result {
nullptr};
3066 g_return_val_if_fail (GNC_IS_ACCOUNT(acc),
nullptr);
3067 g_return_val_if_fail (thunk,
nullptr);
3069 for (
auto node = GET_PRIVATE(acc)->children; !result && node; node = node->next)
3070 result = thunk (static_cast<Account*>(node->data), user_data);
3072 for (
auto node = GET_PRIVATE(acc)->children; !result && node; node = node->next)
3073 result = account_foreach_descendant_breadthfirst_until (static_cast<Account*>(node->data), thunk, user_data);
3079 is_acct_name (
Account *account, gpointer user_data)
3081 auto name {
static_cast<gchar*
>(user_data)};
3088 return (
Account*)account_foreach_descendant_breadthfirst_until (parent, is_acct_name, (
char*)name);
3092 is_acct_code (
Account *account, gpointer user_data)
3094 auto name {
static_cast<gchar*
>(user_data)};
3101 return (
Account*)account_foreach_descendant_breadthfirst_until (parent, is_acct_code, (
char*)code);
3105 is_opening_balance_account (
Account* account, gpointer data)
3107 gnc_commodity* commodity = GNC_COMMODITY(data);
3124 gnc_account_lookup_by_full_name_helper (
const Account *parent,
3131 g_return_val_if_fail(GNC_IS_ACCOUNT(parent),
nullptr);
3132 g_return_val_if_fail(names,
nullptr);
3135 ppriv = GET_PRIVATE(parent);
3136 for (node = ppriv->children; node; node = node->next)
3140 priv = GET_PRIVATE(account);
3141 if (g_strcmp0(priv->accountName, names[0]) == 0)
3145 if (names[1] ==
nullptr)
3149 if (!priv->children)
3153 found = gnc_account_lookup_by_full_name_helper(account, &names[1]);
3154 if (found !=
nullptr)
3174 g_return_val_if_fail(GNC_IS_ACCOUNT(any_acc),
nullptr);
3175 g_return_val_if_fail(name,
nullptr);
3178 rpriv = GET_PRIVATE(root);
3179 while (rpriv->parent)
3181 root = rpriv->parent;
3182 rpriv = GET_PRIVATE(root);
3185 found = gnc_account_lookup_by_full_name_helper(root, names);
3194 gnc_commodity* commodity)
3197 auto rpriv{GET_PRIVATE(root)};
3198 for (
auto node = rpriv->children; node; node = node->next)
3200 auto account{
static_cast<Account*
>(node->data)};
3211 retval = g_list_prepend(retval, account);
3216 for (
auto node = rpriv->children; node; node = node->next)
3218 auto account{
static_cast<Account*
>(node->data)};
3224 retval = g_list_concat(result, retval);
3237 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3238 g_return_if_fail(thunk);
3240 priv = GET_PRIVATE(acc);
3241 for (node = priv->children; node; node = node->next)
3243 thunk (static_cast<Account*>(node->data), user_data);
3252 account_foreach_descendant (acc, thunk, user_data, FALSE);
3260 gpointer result {
nullptr};
3262 g_return_val_if_fail (GNC_IS_ACCOUNT(acc),
nullptr);
3263 g_return_val_if_fail (thunk,
nullptr);
3265 auto priv{GET_PRIVATE(acc)};
3267 for (
auto node = priv->children; node; node = node->next)
3269 auto child =
static_cast<Account*
>(node->data);
3270 result = thunk (child, user_data);
3285 return GET_PRIVATE(acc)->type;
3289 qofAccountGetTypeString (
const Account *acc)
3291 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3296 qofAccountSetType (
Account *acc,
const char *type_string)
3298 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3299 g_return_if_fail(type_string);
3306 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3307 return GET_PRIVATE(acc)->accountName;
3316 const gchar **names;
3321 if (
nullptr == account)
3322 return g_strdup(
"");
3325 g_return_val_if_fail(GNC_IS_ACCOUNT(account), g_strdup(
""));
3328 priv = GET_PRIVATE(account);
3330 return g_strdup(
"");
3335 for (a = account; a; a = priv->parent)
3337 priv = GET_PRIVATE(a);
3343 names = (
const gchar **)g_malloc(level *
sizeof(gchar *));
3344 names[--level] =
nullptr;
3345 for (a = account; level > 0; a = priv->parent)
3347 priv = GET_PRIVATE(a);
3348 names[--level] = priv->accountName;
3352 fullname = g_strjoinv(account_separator, (gchar **)names);
3361 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3362 return GET_PRIVATE(acc)->accountCode;
3368 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3369 return GET_PRIVATE(acc)->description;
3375 GValue v = G_VALUE_INIT;
3376 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3377 auto rv = get_kvp_string_tag (acc,
"color", &v);
3385 GValue v = G_VALUE_INIT;
3386 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0);
3387 auto rv = get_kvp_string_tag (acc,
"filter", &v);
3395 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0);
3396 GValue v = G_VALUE_INIT;
3397 auto rv = get_kvp_string_tag (acc,
"sort-order", &v);
3405 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
3406 GValue v = G_VALUE_INIT;
3407 auto rv = !g_strcmp0 (get_kvp_string_tag (acc,
"sort-reversed", &v),
"true");
3415 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3416 GValue v = G_VALUE_INIT;
3417 auto rv = get_kvp_string_tag (acc,
"notes", &v);
3425 g_return_val_if_fail (GNC_IS_ACCOUNT(acc),
nullptr);
3426 g_return_val_if_fail (tag && *tag,
nullptr);
3428 GValue v = G_VALUE_INIT;
3429 qof_instance_get_path_kvp (QOF_INSTANCE (acc), &v, {
"associated-account", tag });
3431 auto guid =
static_cast<GncGUID*
>(G_VALUE_HOLDS_BOXED (&v) ? g_value_get_boxed(&v) :
nullptr);
3447 GValue v = G_VALUE_INIT;
3448 const char *s =
nullptr;
3449 gnc_commodity_table *
table;
3450 gnc_commodity *retval =
nullptr;
3452 if (!acc)
return nullptr;
3453 qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, {
"old-currency"});
3454 if (G_VALUE_HOLDS_STRING (&v))
3455 s = g_value_get_string (&v);
3459 retval = gnc_commodity_table_lookup_unique (
table, s);
3469 if (!GNC_IS_ACCOUNT(acc))
3471 return GET_PRIVATE(acc)->commodity;
3476 gnc_commodity * commodity;
3477 g_return_val_if_fail (account,
nullptr);
3484 const Account *parent_account = account;
3502 while (parent_account);
3514 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3516 priv = GET_PRIVATE(acc);
3517 priv->starting_balance = start_baln;
3518 priv->balance_dirty = TRUE;
3523 const gnc_numeric start_baln)
3527 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3529 priv = GET_PRIVATE(acc);
3530 priv->starting_cleared_balance = start_baln;
3531 priv->balance_dirty = TRUE;
3536 const gnc_numeric start_baln)
3540 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3542 priv = GET_PRIVATE(acc);
3543 priv->starting_reconciled_balance = start_baln;
3544 priv->balance_dirty = TRUE;
3550 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3551 return GET_PRIVATE(acc)->balance;
3557 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3558 return GET_PRIVATE(acc)->cleared_balance;
3564 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3565 return GET_PRIVATE(acc)->reconciled_balance;
3569 xaccAccountGetProjectedMinimumBalance (
const Account *acc)
3572 std::optional<gnc_numeric> minimum;
3574 auto before_today_end = [&minimum, today](
const Split *s) ->
bool 3584 return minimum ? *minimum : gnc_numeric_zero();
3592 GetBalanceAsOfDate (
Account *acc,
time64 date, std::function<gnc_numeric(Split*)> split_to_numeric)
3594 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3599 auto is_before_date = [date](
auto s) ->
bool 3603 return latest_split ? split_to_numeric (latest_split) : gnc_numeric_zero();
3613 xaccAccountGetNoclosingBalanceAsOfDate (
Account *acc,
time64 date)
3628 xaccAccountGetPresentBalance (
const Account *acc)
3630 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3647 xaccAccountConvertBalanceToCurrency(
const Account *acc,
3648 gnc_numeric balance,
3649 const gnc_commodity *balance_currency,
3650 const gnc_commodity *new_currency)
3659 book = gnc_account_get_book (acc);
3663 pdb, balance, balance_currency, new_currency);
3673 xaccAccountConvertBalanceToCurrencyAsOfDate(
const Account *acc,
3674 gnc_numeric balance,
3675 const gnc_commodity *balance_currency,
3676 const gnc_commodity *new_currency,
3686 book = gnc_account_get_book (acc);
3690 pdb, balance, balance_currency, new_currency, date);
3701 xaccAccountGetXxxBalanceInCurrency (
const Account *acc,
3702 xaccGetBalanceFn fn,
3703 const gnc_commodity *report_currency)
3706 gnc_numeric balance;
3708 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3709 g_return_val_if_fail(fn, gnc_numeric_zero());
3710 g_return_val_if_fail(GNC_IS_COMMODITY(report_currency), gnc_numeric_zero());
3712 priv = GET_PRIVATE(acc);
3714 balance = xaccAccountConvertBalanceToCurrency(acc, balance,
3721 xaccAccountGetXxxBalanceAsOfDateInCurrency(
Account *acc,
time64 date,
3722 xaccGetBalanceAsOfDateFn fn,
3723 const gnc_commodity *report_commodity)
3727 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3728 g_return_val_if_fail(fn, gnc_numeric_zero());
3729 g_return_val_if_fail(GNC_IS_COMMODITY(report_commodity), gnc_numeric_zero());
3731 priv = GET_PRIVATE(acc);
3732 return xaccAccountConvertBalanceToCurrencyAsOfDate(
3733 acc, fn(acc, date), priv->commodity, report_commodity, date);
3741 const gnc_commodity *currency;
3742 gnc_numeric balance;
3743 xaccGetBalanceFn fn;
3744 xaccGetBalanceAsOfDateFn asOfDateFn;
3755 xaccAccountBalanceHelper (
Account *acc, gpointer data)
3758 gnc_numeric balance;
3760 if (!cb->fn || !cb->currency)
3762 balance = xaccAccountGetXxxBalanceInCurrency (acc, cb->fn, cb->currency);
3769 xaccAccountBalanceAsOfDateHelper (
Account *acc, gpointer data)
3772 gnc_numeric balance;
3774 g_return_if_fail (cb->asOfDateFn && cb->currency);
3776 balance = xaccAccountGetXxxBalanceAsOfDateInCurrency (
3777 acc, cb->date, cb->asOfDateFn, cb->currency);
3796 xaccAccountGetXxxBalanceInCurrencyRecursive (
const Account *acc,
3797 xaccGetBalanceFn fn,
3798 const gnc_commodity *report_commodity,
3799 gboolean include_children)
3801 gnc_numeric balance;
3803 if (!acc)
return gnc_numeric_zero ();
3804 if (!report_commodity)
3806 if (!report_commodity)
3807 return gnc_numeric_zero();
3809 balance = xaccAccountGetXxxBalanceInCurrency (acc, fn, report_commodity);
3813 if (include_children)
3820 cb.balance = balance;
3826 balance = cb.balance;
3833 xaccAccountGetXxxBalanceAsOfDateInCurrencyRecursive (
3835 const gnc_commodity *report_commodity, gboolean include_children)
3837 gnc_numeric balance;
3839 g_return_val_if_fail(acc, gnc_numeric_zero());
3840 if (!report_commodity)
3842 if (!report_commodity)
3843 return gnc_numeric_zero();
3845 balance = xaccAccountGetXxxBalanceAsOfDateInCurrency(
3846 acc, date, fn, report_commodity);
3850 if (include_children)
3857 cb.balance = balance;
3859 CurrencyBalance cb = { report_commodity, balance,
nullptr, fn, date };
3863 balance = cb.balance;
3870 xaccAccountGetBalanceInCurrency (
const Account *acc,
3871 const gnc_commodity *report_commodity,
3872 gboolean include_children)
3875 rc = xaccAccountGetXxxBalanceInCurrencyRecursive (
3877 PINFO(
" baln=%" G_GINT64_FORMAT
"/%" G_GINT64_FORMAT, rc.num, rc.denom);
3883 xaccAccountGetClearedBalanceInCurrency (
const Account *acc,
3884 const gnc_commodity *report_commodity,
3885 gboolean include_children)
3887 return xaccAccountGetXxxBalanceInCurrencyRecursive (
3893 xaccAccountGetReconciledBalanceInCurrency (
const Account *acc,
3894 const gnc_commodity *report_commodity,
3895 gboolean include_children)
3897 return xaccAccountGetXxxBalanceInCurrencyRecursive (
3903 xaccAccountGetPresentBalanceInCurrency (
const Account *acc,
3904 const gnc_commodity *report_commodity,
3905 gboolean include_children)
3907 return xaccAccountGetXxxBalanceAsOfDateInCurrencyRecursive (
3914 xaccAccountGetProjectedMinimumBalanceInCurrency (
3916 const gnc_commodity *report_commodity,
3917 gboolean include_children)
3919 return xaccAccountGetXxxBalanceInCurrencyRecursive (
3920 acc, xaccAccountGetProjectedMinimumBalance, report_commodity,
3927 gboolean include_children)
3929 return xaccAccountGetXxxBalanceAsOfDateInCurrencyRecursive (
3937 gboolean include_children)
3939 return xaccAccountGetXxxBalanceAsOfDateInCurrencyRecursive
3940 (acc, date, xaccAccountGetNoclosingBalanceAsOfDate,
3941 report_commodity, include_children);
3956 xaccAccountGetNoclosingBalanceChangeForPeriod (
Account *acc,
time64 t1,
3957 time64 t2, gboolean recurse)
3968 const gnc_commodity *currency;
3969 gnc_numeric balanceChange;
3975 xaccAccountBalanceChangeHelper (
Account *acc, gpointer data)
3983 gnc_numeric balanceChange_conv = xaccAccountConvertBalanceToCurrencyAsOfDate(acc, balanceChange,
xaccAccountGetCommodity(acc), cbdiff->currency, cbdiff->t2);
3984 cbdiff->balanceChange =
gnc_numeric_add (cbdiff->balanceChange, balanceChange_conv,
3990 xaccAccountGetNoclosingBalanceChangeInCurrencyForPeriod (
Account *acc,
time64 t1,
3991 time64 t2, gboolean recurse)
4006 balanceChange = cbdiff.balanceChange;
4008 return balanceChange;
4015 xaccAccountGetSplits (
const Account *account)
4017 return GNC_IS_ACCOUNT(account) ? GET_PRIVATE(account)->splits : SplitsVec{};
4023 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
4024 auto priv{GET_PRIVATE(acc)};
4025 return std::accumulate (priv->splits.rbegin(), priv->splits.rend(),
4026 static_cast<GList*
>(
nullptr), g_list_prepend);
4030 xaccAccountGetSplitsSize (
const Account *account)
4032 return GNC_IS_ACCOUNT(account) ? GET_PRIVATE(account)->splits.size() : 0;
4035 gboolean gnc_account_and_descendants_empty (
Account *acc)
4037 g_return_val_if_fail (GNC_IS_ACCOUNT (acc), FALSE);
4038 auto priv = GET_PRIVATE (acc);
4039 if (!priv->splits.empty())
return FALSE;
4040 for (
auto *n = priv->children; n; n = n->next)
4042 if (!gnc_account_and_descendants_empty (static_cast<Account*>(n->data)))
4051 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
4052 return g_list_copy(GET_PRIVATE(acc)->lots);
4057 gboolean (*match_func)(GNCLot *lot,
4058 gpointer user_data),
4059 gpointer user_data, GCompareFunc sort_func)
4063 GList *retval =
nullptr;
4065 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
4067 priv = GET_PRIVATE(acc);
4068 for (lot_list = priv->lots; lot_list; lot_list = lot_list->next)
4070 GNCLot *lot =
static_cast<GNCLot*
>(lot_list->data);
4076 if (match_func && !(match_func)(lot, user_data))
4080 retval = g_list_prepend (retval, lot);
4084 retval = g_list_sort (retval, sort_func);
4091 gpointer (*proc)(GNCLot *lot,
void *data),
void *data)
4095 gpointer result =
nullptr;
4097 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
4098 g_return_val_if_fail(proc,
nullptr);
4100 priv = GET_PRIVATE(acc);
4101 for (node = priv->lots; node; node = node->next)
4102 if ((result = proc((GNCLot *)node->data, data)))
4109 set_boolean_key (
Account *acc, std::vector<std::string>
const & path, gboolean option)
4111 GValue v = G_VALUE_INIT;
4112 g_return_if_fail(GNC_IS_ACCOUNT(acc));
4114 g_value_init (&v, G_TYPE_BOOLEAN);
4115 g_value_set_boolean (&v, option);
4117 qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v, path);
4124 boolean_from_key (
const Account *acc, std::vector<std::string>
const & path)
4126 GValue v = G_VALUE_INIT;
4127 gboolean retval = FALSE;
4128 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4129 qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, path);
4130 if (G_VALUE_HOLDS_INT64 (&v))
4131 retval = (g_value_get_int64 (&v) != 0);
4132 if (G_VALUE_HOLDS_BOOLEAN (&v))
4133 retval = (g_value_get_boolean (&v));
4134 if (G_VALUE_HOLDS_STRING (&v))
4135 retval = !strcmp (g_value_get_string (&v),
"true");
4147 return boolean_from_key(acc, {
"tax-related"});
4153 set_boolean_key(acc, {
"tax-related"}, tax_related);
4159 GValue v = G_VALUE_INIT;
4160 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4161 qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, {
"tax-US",
"code"});
4162 return G_VALUE_HOLDS_STRING (&v) ? g_value_get_string (&v) :
nullptr;
4168 set_kvp_string_path (acc, {
"tax-US",
"code"}, code);
4174 GValue v = G_VALUE_INIT;
4175 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4176 qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, {
"tax-US",
"payer-name-source"});
4177 return G_VALUE_HOLDS_STRING (&v) ? g_value_get_string (&v) :
nullptr;
4183 set_kvp_string_path (acc, {
"tax-US",
"payer-name-source"}, source);
4189 gint64 copy_number = 0;
4190 GValue v = G_VALUE_INIT;
4191 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4192 qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, {
"tax-US",
"copy-number"});
4193 if (G_VALUE_HOLDS_INT64 (&v))
4194 copy_number = g_value_get_int64 (&v);
4197 return (copy_number == 0) ? 1 : copy_number;
4203 g_return_if_fail(GNC_IS_ACCOUNT(acc));
4205 if (copy_number != 0)
4207 GValue v = G_VALUE_INIT;
4208 g_value_init (&v, G_TYPE_INT64);
4209 g_value_set_int64 (&v, copy_number);
4210 qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v, {
"tax-US",
"copy-number"});
4215 qof_instance_set_path_kvp (QOF_INSTANCE (acc),
nullptr, {
"tax-US",
"copy-number"});
4228 return _(dflt_acct_debit_str);
4230 auto result = gnc_acct_debit_strs.find(acct_type);
4231 if (result != gnc_acct_debit_strs.end())
4232 return _(result->second);
4234 return _(dflt_acct_debit_str);
4240 return _(dflt_acct_credit_str);
4242 auto result = gnc_acct_credit_strs.find(acct_type);
4243 if (result != gnc_acct_credit_strs.end())
4244 return _(result->second);
4246 return _(dflt_acct_credit_str);
4255 return boolean_from_key(acc, {
"placeholder"});
4261 set_boolean_key(acc, {
"placeholder"}, val);
4267 return boolean_from_key(acc, {
"import-append-text"});
4273 set_boolean_key(acc, {
"import-append-text"}, val);
4282 GValue v = G_VALUE_INIT;
4283 auto rv = !g_strcmp0 (get_kvp_string_tag (acc,
"equity-type", &v),
4294 set_kvp_string_tag(acc,
"equity-type", val ?
"opening-balance" :
nullptr);
4300 GList *descendants, *node;
4303 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), PLACEHOLDER_NONE);
4307 for (node = descendants; node; node = node->next)
4310 ret = PLACEHOLDER_CHILD;
4314 g_list_free(descendants);
4324 return boolean_from_key (acc, {KEY_RECONCILE_INFO,
"auto-interest-transfer"});
4330 set_boolean_key (acc, {KEY_RECONCILE_INFO,
"auto-interest-transfer"}, val);
4339 return boolean_from_key (acc, {
"hidden"});
4345 set_boolean_key (acc, {
"hidden"}, val);
4353 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4357 priv = GET_PRIVATE(acc);
4358 while ((acc = priv->parent) !=
nullptr)
4360 priv = GET_PRIVATE(acc);
4375 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4376 g_return_val_if_fail(GNC_IS_ACCOUNT(ancestor), FALSE);
4379 while (parent && parent != ancestor)
4380 parent = GET_PRIVATE(parent)->parent;
4382 return (parent == ancestor);
4391 #define GNC_RETURN_ENUM_AS_STRING(x) case (ACCT_TYPE_ ## x): return #x; 4398 GNC_RETURN_ENUM_AS_STRING(NONE);
4399 GNC_RETURN_ENUM_AS_STRING(BANK);
4400 GNC_RETURN_ENUM_AS_STRING(CASH);
4401 GNC_RETURN_ENUM_AS_STRING(CREDIT);
4402 GNC_RETURN_ENUM_AS_STRING(ASSET);
4403 GNC_RETURN_ENUM_AS_STRING(LIABILITY);
4404 GNC_RETURN_ENUM_AS_STRING(STOCK);
4405 GNC_RETURN_ENUM_AS_STRING(MUTUAL);
4406 GNC_RETURN_ENUM_AS_STRING(CURRENCY);
4407 GNC_RETURN_ENUM_AS_STRING(INCOME);
4408 GNC_RETURN_ENUM_AS_STRING(EXPENSE);
4409 GNC_RETURN_ENUM_AS_STRING(EQUITY);
4410 GNC_RETURN_ENUM_AS_STRING(RECEIVABLE);
4411 GNC_RETURN_ENUM_AS_STRING(PAYABLE);
4412 GNC_RETURN_ENUM_AS_STRING(ROOT);
4413 GNC_RETURN_ENUM_AS_STRING(TRADING);
4414 GNC_RETURN_ENUM_AS_STRING(CHECKING);
4415 GNC_RETURN_ENUM_AS_STRING(SAVINGS);
4416 GNC_RETURN_ENUM_AS_STRING(MONEYMRKT);
4417 GNC_RETURN_ENUM_AS_STRING(CREDITLINE);
4419 PERR (
"asked to translate unknown account type %d.\n", type);
4425 #undef GNC_RETURN_ENUM_AS_STRING 4427 #define GNC_RETURN_ON_MATCH(x) \ 4428 if(g_strcmp0(#x, (str)) == 0) { *type = ACCT_TYPE_ ## x; return(TRUE); } 4434 GNC_RETURN_ON_MATCH(NONE);
4435 GNC_RETURN_ON_MATCH(BANK);
4436 GNC_RETURN_ON_MATCH(CASH);
4437 GNC_RETURN_ON_MATCH(CREDIT);
4438 GNC_RETURN_ON_MATCH(ASSET);
4439 GNC_RETURN_ON_MATCH(LIABILITY);
4440 GNC_RETURN_ON_MATCH(STOCK);
4441 GNC_RETURN_ON_MATCH(MUTUAL);
4442 GNC_RETURN_ON_MATCH(CURRENCY);
4443 GNC_RETURN_ON_MATCH(INCOME);
4444 GNC_RETURN_ON_MATCH(EXPENSE);
4445 GNC_RETURN_ON_MATCH(EQUITY);
4446 GNC_RETURN_ON_MATCH(RECEIVABLE);
4447 GNC_RETURN_ON_MATCH(PAYABLE);
4448 GNC_RETURN_ON_MATCH(ROOT);
4449 GNC_RETURN_ON_MATCH(TRADING);
4450 GNC_RETURN_ON_MATCH(CHECKING);
4451 GNC_RETURN_ON_MATCH(SAVINGS);
4452 GNC_RETURN_ON_MATCH(MONEYMRKT);
4453 GNC_RETURN_ON_MATCH(CREDITLINE);
4455 PERR(
"asked to translate unknown account type string %s.\n",
4456 str ? str :
"(null)");
4461 #undef GNC_RETURN_ON_MATCH 4507 return _(account_type_name [type]);
4549 PERR(
"bad account type: %d", type);
4595 PERR(
"bad account type: %d", type);
4702 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4704 priv = GET_PRIVATE(acc);
4716 GValue v = G_VALUE_INIT;
4717 gboolean retval = FALSE;
4718 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4719 qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, {KEY_RECONCILE_INFO,
"last-date"});
4720 if (G_VALUE_HOLDS_INT64 (&v))
4721 date = g_value_get_int64 (&v);
4740 GValue v = G_VALUE_INIT;
4741 g_return_if_fail(GNC_IS_ACCOUNT(acc));
4743 g_value_init (&v, G_TYPE_INT64);
4744 g_value_set_int64 (&v, last_date);
4746 qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v, {KEY_RECONCILE_INFO,
"last-date"});
4757 int *months,
int *days)
4759 GValue v1 = G_VALUE_INIT, v2 = G_VALUE_INIT;
4760 int64_t m = 0, d = 0;
4761 gboolean retval = FALSE;
4763 if (!acc)
return FALSE;
4764 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4765 qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v1,
4766 {KEY_RECONCILE_INFO,
"last-interval",
"months"});
4767 qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v2,
4768 {KEY_RECONCILE_INFO,
"last-interval",
"days"});
4769 if (G_VALUE_HOLDS_INT64 (&v1))
4770 m = g_value_get_int64 (&v1);
4771 if (G_VALUE_HOLDS_INT64 (&v2))
4772 d = g_value_get_int64 (&v2);
4781 g_value_unset (&v1);
4782 g_value_unset (&v2);
4792 GValue v1 = G_VALUE_INIT, v2 = G_VALUE_INIT;
4793 g_return_if_fail(GNC_IS_ACCOUNT(acc));
4795 g_value_init (&v1, G_TYPE_INT64);
4796 g_value_set_int64 (&v1, months);
4797 g_value_init (&v2, G_TYPE_INT64);
4798 g_value_set_int64 (&v2, days);
4800 qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v1,
4801 {KEY_RECONCILE_INFO,
"last-interval",
"months"});
4802 qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v2,
4803 {KEY_RECONCILE_INFO,
"last-interval",
"days"});
4806 g_value_unset (&v1);
4807 g_value_unset (&v2);
4817 gboolean retval = FALSE;
4818 GValue v = G_VALUE_INIT;
4819 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4820 qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v,
4821 {KEY_RECONCILE_INFO, KEY_POSTPONE,
"date"});
4822 if (G_VALUE_HOLDS_INT64 (&v))
4823 date = g_value_get_int64 (&v);
4828 *postpone_date = date;
4841 GValue v = G_VALUE_INIT;
4842 g_return_if_fail(GNC_IS_ACCOUNT(acc));
4844 g_value_init (&v, G_TYPE_INT64);
4845 g_value_set_int64 (&v, postpone_date);
4847 qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v,
4848 {KEY_RECONCILE_INFO, KEY_POSTPONE,
"date"});
4859 gnc_numeric *balance)
4861 gnc_numeric bal = gnc_numeric_zero ();
4862 GValue v = G_VALUE_INIT;
4863 gboolean retval = FALSE;
4864 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4865 qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v,
4866 {KEY_RECONCILE_INFO, KEY_POSTPONE,
"balance"});
4867 if (G_VALUE_HOLDS_BOXED (&v))
4869 bal = *(gnc_numeric*)g_value_get_boxed (&v);
4887 GValue v = G_VALUE_INIT;
4888 g_return_if_fail(GNC_IS_ACCOUNT(acc));
4890 g_value_init (&v, GNC_TYPE_NUMERIC);
4891 g_value_set_boxed (&v, &balance);
4893 qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v,
4894 {KEY_RECONCILE_INFO, KEY_POSTPONE,
"balance"});
4910 qof_instance_set_path_kvp (QOF_INSTANCE(acc),
nullptr, {KEY_RECONCILE_INFO, KEY_POSTPONE});
4921 GValue v = G_VALUE_INIT;
4922 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4923 qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, {
"last-num"});
4924 return G_VALUE_HOLDS_STRING (&v) ? g_value_get_string (&v) :
nullptr;
4933 GValue v = G_VALUE_INIT;
4934 g_return_if_fail(GNC_IS_ACCOUNT(acc));
4935 g_value_init (&v, G_TYPE_STRING);
4937 g_value_set_static_string (&v, num);
4939 qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v, {
"last-num"});
4950 gnc_numeric *balance)
4952 g_return_val_if_fail (GNC_IS_ACCOUNT(acc),
false);
4954 if (GET_PRIVATE(acc)->higher_balance_limit.has_value())
4956 *balance = GET_PRIVATE(acc)->higher_balance_limit.value();
4965 gnc_numeric bal = gnc_numeric_create (1,0);
4966 GValue v = G_VALUE_INIT;
4967 gboolean retval =
false;
4969 qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, {KEY_BALANCE_LIMIT,
4970 KEY_BALANCE_HIGHER_LIMIT_VALUE});
4971 if (G_VALUE_HOLDS_BOXED(&v))
4973 bal = *(gnc_numeric*)g_value_get_boxed (&v);
4983 GET_PRIVATE(acc)->higher_balance_limit = bal;
4990 gnc_numeric *balance)
4992 g_return_val_if_fail (GNC_IS_ACCOUNT(acc),
false);
4994 if (GET_PRIVATE(acc)->lower_balance_limit.has_value())
4996 *balance = GET_PRIVATE(acc)->lower_balance_limit.value();
5005 gnc_numeric bal = gnc_numeric_create (1,0);
5006 GValue v = G_VALUE_INIT;
5007 gboolean retval =
false;
5009 qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, {KEY_BALANCE_LIMIT,
5010 KEY_BALANCE_LOWER_LIMIT_VALUE});
5011 if (G_VALUE_HOLDS_BOXED(&v))
5013 bal = *(gnc_numeric*)g_value_get_boxed (&v);
5023 GET_PRIVATE(acc)->lower_balance_limit = bal;
5030 set_balance_limits (
Account *acc, gnc_numeric balance, gboolean higher)
5032 gnc_numeric balance_limit;
5033 gboolean balance_limit_valid;
5034 std::vector<std::string> path {KEY_BALANCE_LIMIT};
5038 path.push_back (KEY_BALANCE_HIGHER_LIMIT_VALUE);
5043 path.push_back (KEY_BALANCE_LOWER_LIMIT_VALUE);
5049 GValue v = G_VALUE_INIT;
5050 g_value_init (&v, GNC_TYPE_NUMERIC);
5051 g_value_set_boxed (&v, &balance);
5054 qof_instance_set_path_kvp (QOF_INSTANCE(acc), &v, path);
5057 GET_PRIVATE(acc)->higher_balance_limit = balance;
5061 GET_PRIVATE(acc)->lower_balance_limit = balance;
5072 g_return_if_fail (GNC_IS_ACCOUNT(acc));
5077 set_balance_limits (acc, balance,
true);
5083 g_return_if_fail (GNC_IS_ACCOUNT(acc));
5088 set_balance_limits (acc, balance,
false);
5093 clear_balance_limits (
Account *acc, gboolean higher)
5095 gnc_numeric balance_limit;
5096 gboolean balance_limit_valid;
5097 std::vector<std::string> path {KEY_BALANCE_LIMIT};
5101 path.push_back (KEY_BALANCE_HIGHER_LIMIT_VALUE);
5106 path.push_back (KEY_BALANCE_LOWER_LIMIT_VALUE);
5110 if (balance_limit_valid)
5113 qof_instance_set_path_kvp (QOF_INSTANCE(acc),
nullptr, path);
5114 qof_instance_slot_path_delete_if_empty (QOF_INSTANCE(acc), {KEY_BALANCE_LIMIT});
5116 GET_PRIVATE(acc)->higher_balance_limit.reset();
5118 GET_PRIVATE(acc)->lower_balance_limit.reset();
5127 g_return_if_fail (GNC_IS_ACCOUNT(acc));
5129 clear_balance_limits (acc,
true);
5135 g_return_if_fail (GNC_IS_ACCOUNT(acc));
5137 clear_balance_limits (acc,
false);
5143 g_return_val_if_fail (GNC_IS_ACCOUNT(acc),
false);
5145 if (!GET_PRIVATE(acc)->include_sub_account_balances.has_value())
5147 gboolean inc_sub = boolean_from_key (acc, {KEY_BALANCE_LIMIT,
5148 KEY_BALANCE_INCLUDE_SUB_ACCTS});
5150 GET_PRIVATE(acc)->include_sub_account_balances = inc_sub;
5152 return GET_PRIVATE(acc)->include_sub_account_balances.value();
5158 g_return_if_fail (GNC_IS_ACCOUNT(acc));
5162 GValue v = G_VALUE_INIT;
5163 g_value_init (&v, G_TYPE_BOOLEAN);
5164 g_value_set_boolean (&v, inc_sub);
5165 std::vector<std::string> path {KEY_BALANCE_LIMIT,
5166 KEY_BALANCE_INCLUDE_SUB_ACCTS};
5169 qof_instance_set_path_kvp (QOF_INSTANCE(acc), &v, path);
5171 qof_instance_set_path_kvp (QOF_INSTANCE(acc),
nullptr, path);
5172 GET_PRIVATE(acc)->include_sub_account_balances = inc_sub;
5183 GetOrMakeOrphanAccount (
Account *root, gnc_commodity * currency)
5188 g_return_val_if_fail (root,
nullptr);
5193 PERR (
"No currency specified!");
5197 accname = g_strconcat (_(
"Orphaned Gains"),
"-",
5213 _(
"Realized Gains or Losses from " 5214 "Commodity or Trading Accounts " 5215 "that haven't been recorded elsewhere."));
5230 GValue v = G_VALUE_INIT;
5231 std::vector<std::string> path {KEY_LOT_MGMT,
"gains-acct",
5236 g_return_val_if_fail (acc !=
nullptr,
nullptr);
5237 qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, path);
5238 if (G_VALUE_HOLDS_BOXED (&v))
5239 guid = (
GncGUID*)g_value_get_boxed (&v);
5240 if (guid ==
nullptr)
5247 GValue vr = G_VALUE_INIT;
5248 g_value_init (&vr, GNC_TYPE_GUID);
5249 g_value_set_boxed (&vr, guid);
5250 qof_instance_set_path_kvp (QOF_INSTANCE (acc), &vr, path);
5251 qof_instance_set_dirty (QOF_INSTANCE (acc));
5252 g_value_unset (&vr);
5261 return gains_account;
5273 set_kvp_string_tag (acc,
"old-price-source", src);
5282 static char *source =
nullptr;
5283 if (!acc)
return nullptr;
5289 GValue v = G_VALUE_INIT;
5290 auto rv = get_kvp_string_tag (acc,
"old-price-source", &v);
5303 set_kvp_string_tag (acc,
"old-quote-tz", tz);
5312 if (!acc)
return nullptr;
5314 GValue v = G_VALUE_INIT;
5315 auto rv = get_kvp_string_tag (acc,
"old-quote-tz", &v);
5326 GValue v = G_VALUE_INIT;
5334 g_value_init (&v, G_TYPE_INT64);
5335 g_value_set_int64 (&v, status);
5336 qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v,
5337 {KEY_RECONCILE_INFO, KEY_INCLUDE_CHILDREN});
5353 GValue v = G_VALUE_INIT;
5355 if (!acc)
return FALSE;
5356 qof_instance_get_path_kvp (QOF_INSTANCE (acc), &v,
5357 {KEY_RECONCILE_INFO, KEY_INCLUDE_CHILDREN});
5358 retval = G_VALUE_HOLDS_INT64 (&v) ? g_value_get_int64 (&v) : FALSE;
5369 auto has_description = [description](
const Split* s) ->
bool 5393 GList *children, *node;
5396 g_return_if_fail(GNC_IS_ACCOUNT(to_parent));
5397 g_return_if_fail(GNC_IS_ACCOUNT(from_parent));
5400 from_priv = GET_PRIVATE(from_parent);
5401 if (!from_priv->children)
5405 children = g_list_copy(from_priv->children);
5406 for (node = children; node; node = g_list_next(node))
5408 g_list_free(children);
5418 GList *node_a, *node_b, *work, *worker;
5420 g_return_if_fail(GNC_IS_ACCOUNT(parent));
5422 ppriv = GET_PRIVATE(parent);
5423 for (node_a = ppriv->children; node_a; node_a = node_a->next)
5427 priv_a = GET_PRIVATE(acc_a);
5428 for (node_b = node_a->next; node_b; node_b = g_list_next(node_b))
5432 priv_b = GET_PRIVATE(acc_b);
5433 if (0 !=
null_strcmp(priv_a->accountName, priv_b->accountName))
5435 if (0 !=
null_strcmp(priv_a->accountCode, priv_b->accountCode))
5437 if (0 !=
null_strcmp(priv_a->description, priv_b->description))
5447 if (priv_a->type != priv_b->type)
5451 if (priv_b->children)
5453 work = g_list_copy(priv_b->children);
5454 for (worker = work; worker; worker = g_list_next(worker))
5466 while (!priv_b->splits.empty())
5467 xaccSplitSetAccount (priv_b->splits.front(), acc_a);
5471 node_b = g_list_previous(node_b);
5486 xaccSplitsBeginStagedTransactionTraversals (SplitsVec& splits)
5488 for (
auto s : splits)
5490 Transaction *trans = s->parent;
5503 xaccSplitsBeginStagedTransactionTraversals(GET_PRIVATE (account)->splits);
5509 if (trans ==
nullptr)
return FALSE;
5511 if (trans->marker < stage)
5513 trans->marker = stage;
5520 static void do_one_account (
Account *account, gpointer data)
5523 std::for_each (priv->splits.begin(), priv->splits.end(),
5524 [](
auto s){ s->parent->marker = 0; });
5534 g_list_foreach(descendants, (GFunc)do_one_account,
nullptr);
5535 g_list_free(descendants);
5541 TransactionCallback thunk,
5546 auto splits = GET_PRIVATE(acc)->splits;
5547 for (
auto s : splits)
5549 auto trans = s->parent;
5550 if (trans && (trans->marker < stage))
5552 trans->marker = stage;
5555 auto retval = thunk(trans, cb_data);
5556 if (retval)
return retval;
5567 TransactionCallback thunk,
5577 priv = GET_PRIVATE(acc);
5578 for (
auto acc_p = priv->children; acc_p; acc_p = g_list_next(acc_p))
5581 stage, thunk, cb_data);
5582 if (retval)
return retval;
5586 for (
auto s : priv->splits)
5589 if (trans && (trans->marker < stage))
5591 trans->marker = stage;
5594 retval = thunk(trans, cb_data);
5595 if (retval)
return retval;
5608 int (*proc)(Transaction *t,
void *data),
5611 if (!acc || !proc)
return 0;
5622 if (!acc || !proc)
return 0;
5633 #define IMAP_FRAME "import-map" 5634 #define IMAP_FRAME_BAYES "import-map-bayes" 5638 gnc_account_imap_find_account (
Account *acc,
5639 const char *category,
5642 GValue v = G_VALUE_INIT;
5645 if (!acc || !key)
return nullptr;
5646 std::vector<std::string> path {IMAP_FRAME};
5648 path.push_back (category);
5649 path.push_back (key);
5650 qof_instance_get_path_kvp (QOF_INSTANCE (acc), &v, path);
5651 if (G_VALUE_HOLDS_BOXED (&v))
5652 guid = (
GncGUID*)g_value_get_boxed (&v);
5659 gnc_account_imap_find_any (QofBook *book,
const char* category,
const char *key)
5664 auto root = gnc_book_get_root_account (book);
5668 for (
auto ptr = accts; ptr; ptr = g_list_next (ptr))
5670 auto tmp_acc =
static_cast<Account*
> (ptr->data);
5672 if (gnc_account_imap_find_account (tmp_acc, category, key))
5678 g_list_free (accts);
5685 gnc_account_imap_add_account (
Account *acc,
5686 const char *category,
5690 GValue v = G_VALUE_INIT;
5691 if (!acc || !key || !added_acc || (strlen (key) == 0))
return;
5692 std::vector<std::string> path {IMAP_FRAME};
5694 path.emplace_back (category);
5695 path.emplace_back (key);
5696 g_value_init (&v, GNC_TYPE_GUID);
5699 qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v, path);
5700 qof_instance_set_dirty (QOF_INSTANCE (acc));
5707 gnc_account_imap_delete_account (
Account *acc,
5708 const char *category,
5711 if (!acc || !key)
return;
5712 std::vector<std::string> path {IMAP_FRAME};
5714 path.emplace_back (category);
5715 path.emplace_back (key);
5717 if (qof_instance_has_path_slot (QOF_INSTANCE (acc), path))
5719 qof_instance_slot_path_delete (QOF_INSTANCE (acc), path);
5721 qof_instance_slot_path_delete_if_empty (QOF_INSTANCE (acc), {IMAP_FRAME, category});
5722 qof_instance_slot_path_delete_if_empty (QOF_INSTANCE (acc), {IMAP_FRAME});
5724 qof_instance_set_dirty (QOF_INSTANCE (acc));
5740 double product_difference;
5745 std::string account_guid;
5746 int64_t token_count;
5754 std::vector<AccountTokenCount> accounts;
5755 int64_t total_count;
5763 std::string account_guid;
5764 int32_t probability;
5768 build_token_info(
char const * suffix, KvpValue * value,
TokenAccountsInfo & tokenInfo)
5772 tokenInfo.total_count += value->get<int64_t>();
5774 tokenInfo.accounts.emplace_back(
AccountTokenCount{std::string{suffix}, value->get<int64_t>()});
5781 static constexpr
int probability_factor = 100000;
5783 static FinalProbabilityVec
5784 build_probabilities(ProbabilityVec
const & first_pass)
5786 FinalProbabilityVec ret;
5787 for (
auto const & first_pass_prob : first_pass)
5789 auto const & account_probability = first_pass_prob.second;
5794 int32_t probability = (account_probability.product /
5795 (account_probability.product + account_probability.product_difference)) * probability_factor;
5796 ret.push_back({first_pass_prob.first, probability});
5802 highest_probability(FinalProbabilityVec
const & probabilities)
5804 AccountInfo ret {
"", std::numeric_limits<int32_t>::min()};
5805 for (
auto const & prob : probabilities)
5806 if (prob.second > ret.probability)
5811 static ProbabilityVec
5812 get_first_pass_probabilities(
Account* acc, GList * tokens)
5817 for (
auto current_token = tokens; current_token; current_token = current_token->next)
5820 auto path = std::string{IMAP_FRAME_BAYES
"/"} + static_cast <
char const *> (current_token->data) +
"/";
5821 qof_instance_foreach_slot_prefix (QOF_INSTANCE (acc), path, &build_token_info, tokenInfo);
5822 for (
auto const & current_account_token : tokenInfo.accounts)
5824 auto item = std::find_if(ret.begin(), ret.end(), [¤t_account_token]
5825 (std::pair<std::string, AccountProbability>
const & a) {
5826 return current_account_token.account_guid == a.first;
5828 if (item != ret.end())
5830 item->second.product = ((double)current_account_token.token_count /
5831 (
double)tokenInfo.total_count) * item->second.product;
5832 item->second.product_difference = ((
double)1 - ((double)current_account_token.token_count /
5833 (
double)tokenInfo.total_count)) * item->second.product_difference;
5839 new_probability.product = ((double)current_account_token.token_count /
5840 (
double)tokenInfo.total_count);
5841 new_probability.product_difference = 1 - (new_probability.product);
5842 ret.push_back({current_account_token.account_guid, std::move(new_probability)});
5850 look_for_old_separator_descendants (
Account *root, std::string
const & full_name,
const gchar *separator)
5852 GList *top_accounts, *ptr;
5856 PINFO(
"Incoming full_name is '%s', current separator is '%s'", full_name.c_str (), separator);
5858 for (ptr = top_accounts; ptr; ptr = g_list_next (ptr))
5862 if (g_str_has_prefix (full_name.c_str (), name))
5864 gint name_len = strlen (name);
5865 const gchar old_sep = full_name[name_len];
5866 if (!g_ascii_isalnum (old_sep))
5868 if (name_len > found_len)
5870 found_sep = full_name[name_len];
5871 found_len = name_len;
5876 g_list_free (top_accounts);
5877 std::string new_name {full_name};
5879 std::replace (new_name.begin (), new_name.end (), found_sep, *separator);
5880 PINFO (
"Return full_name is '%s'", new_name.c_str ());
5885 get_guid_from_account_name (
Account * root, std::string
const & name)
5890 auto temp_account_name = look_for_old_separator_descendants (root, name,
5895 return temp_guid.to_string ();
5899 convert_entry (KvpEntry entry,
Account* root)
5902 auto account_name = entry.first.back();
5903 if (!gnc::GUID::is_valid_guid (account_name))
5909 entry.first.pop_back();
5910 auto guid_str = get_guid_from_account_name (root, account_name);
5911 entry.first.emplace_back (guid_str);
5913 std::string new_key {std::accumulate (entry.first.begin(), entry.first.end(), std::string {})};
5914 new_key = IMAP_FRAME_BAYES + new_key;
5915 return {new_key, entry.second};
5918 static std::vector<FlatKvpEntry>
5921 auto frame = qof_instance_get_slots (QOF_INSTANCE (acc));
5922 auto slot = frame->get_slot ({IMAP_FRAME_BAYES});
5925 auto imap_frame = slot->get<KvpFrame*> ();
5926 auto flat_kvp = imap_frame->flatten_kvp ();
5928 std::vector <FlatKvpEntry> ret;
5929 for (
auto const & flat_entry : flat_kvp)
5931 auto converted_entry = convert_entry (flat_entry, root);
5933 if (converted_entry.first.size())
5934 ret.emplace_back (converted_entry);
5940 convert_imap_account_bayes_to_flat (
Account *acc)
5942 auto frame = qof_instance_get_slots (QOF_INSTANCE (acc));
5943 if (!frame->get_keys().size())
5945 auto flat_imap = get_flat_imap(acc);
5946 if (!flat_imap.size ())
5949 frame->set({IMAP_FRAME_BAYES},
nullptr);
5950 std::for_each(flat_imap.begin(), flat_imap.end(),
5951 [&frame] (FlatKvpEntry
const & entry) {
5952 frame->set({entry.first.c_str()}, entry.second);
5954 qof_instance_set_dirty (QOF_INSTANCE (acc));
5963 imap_convert_bayes_to_flat (QofBook * book)
5965 auto root = gnc_book_get_root_account (book);
5968 for (
auto ptr = accts; ptr; ptr = g_list_next (ptr))
5971 if (convert_imap_account_bayes_to_flat (acc))
5977 g_list_free (accts);
5984 imap_convert_bayes_to_flat_run =
false;
5999 check_import_map_data (QofBook *book)
6001 if (gnc_features_check_used (book, GNC_FEATURE_GUID_FLAT_BAYESIAN) ||
6002 imap_convert_bayes_to_flat_run)
6006 imap_convert_bayes_to_flat (book);
6007 imap_convert_bayes_to_flat_run =
true;
6010 static constexpr
double threshold = .90 * probability_factor;
6018 auto book = gnc_account_get_book(acc);
6019 check_import_map_data (book);
6020 auto first_pass = get_first_pass_probabilities(acc, tokens);
6021 if (!first_pass.size())
6023 auto final_probabilities = build_probabilities(first_pass);
6024 if (!final_probabilities.size())
6026 auto best = highest_probability(final_probabilities);
6027 if (best.account_guid ==
"")
6029 if (best.probability < threshold)
6033 guid = gnc::GUID::from_string(best.account_guid);
6042 change_imap_entry (
Account *acc, std::string
const & path, int64_t token_count)
6044 GValue value = G_VALUE_INIT;
6046 PINFO(
"Source Account is '%s', Count is '%" G_GINT64_FORMAT
"'",
6050 if (qof_instance_has_slot (QOF_INSTANCE(acc), path.c_str ()))
6052 int64_t existing_token_count = 0;
6055 qof_instance_get_path_kvp (QOF_INSTANCE (acc), &value, {path});
6057 if (G_VALUE_HOLDS_INT64 (&value))
6058 existing_token_count = g_value_get_int64 (&value);
6060 PINFO(
"found existing value of '%" G_GINT64_FORMAT
"'", existing_token_count);
6062 token_count = token_count + existing_token_count;
6065 if (!G_IS_VALUE (&value))
6066 g_value_init (&value, G_TYPE_INT64);
6068 g_value_set_int64 (&value, token_count);
6071 qof_instance_set_path_kvp (QOF_INSTANCE (acc), &value, {path});
6073 g_value_unset (&value);
6082 GList *current_token;
6084 char *account_fullname;
6093 check_import_map_data (gnc_account_get_book(acc));
6095 g_return_if_fail (added_acc !=
nullptr);
6099 PINFO(
"account name: '%s'", account_fullname);
6104 for (current_token = g_list_first(tokens); current_token;
6105 current_token = current_token->next)
6111 if (!current_token->data || (*((
char*)current_token->data) ==
'\0'))
6115 PINFO(
"adding token '%s'", (
char*)current_token->data);
6116 auto path = std::string {IMAP_FRAME_BAYES} +
'/' +
static_cast<char*
>(current_token->data) +
'/' + guid_string;
6118 change_imap_entry (acc, path, token_count);
6121 qof_instance_set_dirty (QOF_INSTANCE (acc));
6123 g_free (account_fullname);
6124 g_free (guid_string);
6131 build_non_bayes (
const char *key,
const GValue *value, gpointer user_data)
6133 if (!G_VALUE_HOLDS_BOXED (value))
6137 gchar *guid_string =
nullptr;
6142 guid = (
GncGUID*)g_value_get_boxed (value);
6145 PINFO(
"build_non_bayes: match string '%s', match account guid: '%s'",
6146 (
char*)key, guid_string);
6150 imapInfo_node->source_account = imapInfo->source_account;
6152 imapInfo_node->head = g_strdup (imapInfo->head);
6153 imapInfo_node->match_string = g_strdup (key);
6154 imapInfo_node->category = g_strdup (imapInfo->category);
6155 imapInfo_node->count = g_strdup (
" ");
6157 imapInfo->list = g_list_prepend (imapInfo->list, imapInfo_node);
6159 g_free (guid_string);
6163 build_bayes (
const char *suffix, KvpValue * value,
GncImapInfo & imapInfo)
6166 std::string account_guid {&suffix[guid_start]};
6170 guid = gnc::GUID::from_string (account_guid);
6174 PWARN(
"Invalid GUID string from %s%s", IMAP_FRAME_BAYES, suffix);
6176 auto map_account =
xaccAccountLookup (&guid, gnc_account_get_book (imapInfo.source_account));
6178 auto count = value->get <int64_t> ();
6179 imap_node->source_account = imapInfo.source_account;
6180 imap_node->map_account = map_account;
6181 imap_node->head = g_strdup_printf (
"%s%s", IMAP_FRAME_BAYES, suffix);
6182 imap_node->match_string = g_strndup (&suffix[1], guid_start - 2);
6183 imap_node->category = g_strdup(
" ");
6184 imap_node->count = g_strdup_printf (
"%" G_GINT64_FORMAT, count);
6185 imapInfo.list = g_list_prepend (imapInfo.list, imap_node);
6190 g_free (imapInfo->head);
6191 g_free (imapInfo->category);
6192 g_free (imapInfo->match_string);
6193 g_free (imapInfo->count);
6200 check_import_map_data (gnc_account_get_book (acc));
6204 qof_instance_foreach_slot_prefix (QOF_INSTANCE (acc), IMAP_FRAME_BAYES, &build_bayes, imapInfo);
6205 return g_list_reverse(imapInfo.list);
6211 GList *list =
nullptr;
6215 std::vector<std::string> path {IMAP_FRAME};
6217 path.emplace_back (category);
6219 imapInfo.source_account = acc;
6220 imapInfo.list = list;
6222 imapInfo.head = g_strdup (IMAP_FRAME);
6223 imapInfo.category = g_strdup (category);
6225 if (qof_instance_has_path_slot (QOF_INSTANCE (acc), path))
6227 qof_instance_foreach_slot (QOF_INSTANCE(acc), IMAP_FRAME, category,
6228 build_non_bayes, &imapInfo);
6230 g_free (imapInfo.head);
6231 g_free (imapInfo.category);
6232 return g_list_reverse(imapInfo.list);
6240 GValue v = G_VALUE_INIT;
6241 auto rv = g_strdup (category ?
6242 get_kvp_string_path (acc, {head, category}, &v) :
6243 get_kvp_string_path (acc, {head}, &v));
6251 char *match_string, gboolean empty)
6255 std::vector<std::string> path {head};
6257 path.emplace_back (category);
6259 path.emplace_back (match_string);
6261 if (qof_instance_has_path_slot (QOF_INSTANCE (acc), path))
6265 qof_instance_slot_path_delete_if_empty (QOF_INSTANCE(acc), path);
6267 qof_instance_slot_path_delete (QOF_INSTANCE(acc), path);
6268 PINFO(
"Account is '%s', head is '%s', category is '%s', match_string is'%s'",
6270 qof_instance_set_dirty (QOF_INSTANCE(acc));
6281 auto slots = qof_instance_get_slots_prefix (QOF_INSTANCE (acc), IMAP_FRAME_BAYES);
6282 if (!slots.size())
return;
6284 for (
auto const & entry : slots)
6286 qof_instance_slot_path_delete (QOF_INSTANCE (acc), {entry.first});
6288 qof_instance_set_dirty (QOF_INSTANCE(acc));
6297 destroy_all_child_accounts (
Account *acc, gpointer data)
6304 gnc_account_book_end(QofBook* book)
6306 Account *root_account = gnc_book_get_root_account (book);
6316 accounts = g_list_reverse (accounts);
6317 g_list_foreach (accounts, (GFunc)destroy_all_child_accounts,
nullptr);
6318 g_list_free (accounts);
6331 static QofObject account_object_def =
6334 DI(.e_type = ) GNC_ID_ACCOUNT,
6337 DI(.book_begin = )
nullptr,
6338 DI(.book_end = ) gnc_account_book_end,
6346 gboolean xaccAccountRegister (
void)
6348 static QofParam params[] =
6351 ACCOUNT_NAME_, QOF_TYPE_STRING,
6356 ACCOUNT_CODE_, QOF_TYPE_STRING,
6361 ACCOUNT_DESCRIPTION_, QOF_TYPE_STRING,
6366 ACCOUNT_COLOR_, QOF_TYPE_STRING,
6371 ACCOUNT_FILTER_, QOF_TYPE_STRING,
6376 ACCOUNT_SORT_ORDER_, QOF_TYPE_STRING,
6381 ACCOUNT_SORT_REVERSED_, QOF_TYPE_BOOLEAN,
6386 ACCOUNT_NOTES_, QOF_TYPE_STRING,
6391 ACCOUNT_PRESENT_, QOF_TYPE_NUMERIC,
6395 ACCOUNT_BALANCE_, QOF_TYPE_NUMERIC,
6399 ACCOUNT_CLEARED_, QOF_TYPE_NUMERIC,
6403 ACCOUNT_RECONCILED_, QOF_TYPE_NUMERIC,
6407 ACCOUNT_TYPE_, QOF_TYPE_STRING,
6412 ACCOUNT_FUTURE_MINIMUM_, QOF_TYPE_NUMERIC,
6413 (
QofAccessFunc) xaccAccountGetProjectedMinimumBalance,
nullptr 6416 ACCOUNT_TAX_RELATED, QOF_TYPE_BOOLEAN,
6421 ACCOUNT_OPENING_BALANCE_, QOF_TYPE_BOOLEAN,
6426 ACCOUNT_SCU, QOF_TYPE_INT32,
6431 ACCOUNT_NSCU, QOF_TYPE_BOOLEAN,
6436 ACCOUNT_PARENT, GNC_ID_ACCOUNT,
6445 QOF_PARAM_GUID, QOF_TYPE_GUID,
6456 using AccountSet = std::unordered_set<Account*>;
6457 static void maybe_add_descendants (
Account* acc, gpointer arg)
6459 g_return_if_fail (acc);
6461 if (static_cast <AccountSet*> (arg)->insert (acc).second)
6462 g_list_foreach (GET_PRIVATE(acc)->children, (GFunc) maybe_add_descendants, arg);
6466 gnc_accounts_and_all_descendants (GList *accounts)
6469 g_list_foreach (accounts, (GFunc) maybe_add_descendants, &accset);
6470 return std::accumulate (accset.begin(), accset.end(), (GList*)
nullptr, g_list_prepend);
6477 utest_account_get_private (
Account *acc)
6479 return GET_PRIVATE (acc);
6483 _utest_account_fill_functions(
void)
6487 func->get_private = utest_account_get_private;
6488 func->coll_get_root_account = gnc_coll_get_root_account;
6489 func->xaccFreeAccountChildren = xaccFreeAccountChildren;
6490 func->xaccFreeAccount = xaccFreeAccount;
6491 func->qofAccountSetParent = qofAccountSetParent;
6492 func->gnc_account_lookup_by_full_name_helper =
6493 gnc_account_lookup_by_full_name_helper;
void xaccAccountSetType(Account *acc, GNCAccountType tip)
Set the account's type.
int qof_instance_version_cmp(const QofInstance *left, const QofInstance *right)
Compare two instances, based on their last update times.
gnc_commodity * gnc_commodity_table_insert(gnc_commodity_table *table, gnc_commodity *comm)
Add a new commodity to the commodity table.
Account * gnc_account_get_parent(const Account *acc)
This routine returns a pointer to the parent of the specified account.
void xaccAccountSetFilter(Account *acc, const char *str)
Set the account's Filter.
void xaccAccountSetSortOrder(Account *acc, const char *str)
Set the account's Sort Order.
gint xaccAccountForEachTransaction(const Account *acc, TransactionCallback proc, void *data)
The xaccAccountForEachTransaction() routine will traverse all of the transactions in account and call...
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.
This is the private header for the account structure.
gnc_commodity_table * gnc_commodity_table_get_table(QofBook *book)
Returns the commodity table associated with a book.
gboolean gnc_numeric_equal(gnc_numeric a, gnc_numeric b)
Equivalence predicate: Returns TRUE (1) if a and b represent the same number.
int gnc_account_tree_staged_transaction_traversal(const Account *acc, unsigned int stage, TransactionCallback thunk, void *cb_data)
gnc_account_tree_staged_transaction_traversal() calls thunk on each transaction in the group whose cu...
gboolean xaccAccountGetAutoInterest(const Account *acc)
Get the "auto interest" flag for an account.
holds an account guid and its corresponding integer probability the integer probability is some facto...
const char * xaccAccountGetLastNum(const Account *acc)
Get the last num field of an Account.
GNCAccountType xaccAccountTypeGetFundamental(GNCAccountType t)
Convenience function to return the fundamental type asset/liability/income/expense/equity given an ac...
gchar * gnc_account_get_map_entry(Account *acc, const char *head, const char *category)
Returns the text string pointed to by head and category for the Account, free the returned text...
gboolean gnc_commodity_is_currency(const gnc_commodity *cm)
Checks to see if the specified commodity is an ISO 4217 recognized currency or a legacy currency...
GList LotList
GList of GNCLots.
int gnc_commodity_get_fraction(const gnc_commodity *cm)
Retrieve the fraction for the specified commodity.
gboolean xaccAccountGetSortReversed(const Account *acc)
Get the account's Sort Order direction.
guint32 xaccAccountTypesCompatibleWith(GNCAccountType type)
Return the bitmask of account types compatible with a given type.
void gnc_account_imap_info_destroy(GncImapInfo *imapInfo)
Clean destructor for the imap_info structure of Bayesian mappings.
void gnc_account_append_child(Account *new_parent, Account *child)
This function will remove from the child account any pre-existing parent relationship, and will then add the account as a child of the new parent.
const GncGUID * qof_instance_get_guid(gconstpointer inst)
Return the GncGUID of this instance.
gpointer xaccAccountForEachLot(const Account *acc, gpointer(*proc)(GNCLot *lot, gpointer user_data), gpointer user_data)
The xaccAccountForEachLot() method will apply the function 'proc' to each lot in the account...
time64 xaccTransGetDate(const Transaction *trans)
Retrieve the posted date of the transaction.
GList * gnc_account_get_descendants_sorted(const Account *account)
This function returns a GList containing all the descendants of the specified account, sorted at each level.
gint gnc_account_n_descendants(const Account *account)
Return the number of descendants of the specified account.
gint64 xaccAccountGetTaxUSCopyNumber(const Account *acc)
DOCUMENT ME!
gboolean gnc_account_is_root(const Account *account)
This routine indicates whether the specified account is the root node of an account tree...
SplitList * xaccAccountGetSplitList(const Account *acc)
The xaccAccountGetSplitList() routine returns a pointer to a GList of the splits in the account...
const char * gnc_commodity_get_mnemonic(const gnc_commodity *cm)
Retrieve the mnemonic for the specified commodity.
void xaccAccountSetAssociatedAccount(Account *acc, const char *tag, const Account *assoc_acct)
Set the account's associated account e.g.
gboolean xaccAccountGetNonStdSCU(const Account *acc)
Return boolean, indicating whether this account uses a non-standard SCU.
int xaccAccountGetCommoditySCUi(const Account *acc)
Return the 'internal' SCU setting.
#define GNC_COMMODITY_MAX_FRACTION
Max fraction is 10^9 because 10^10 would require changing it to an int64_t.
const char * qof_string_cache_replace(char const *dst, char const *src)
Same as CACHE_REPLACE below, but safe to call from C++.
gchar * gnc_g_list_stringjoin(GList *list_of_strings, const gchar *sep)
Return a string joining a GList whose elements are gchar* strings.
gnc_commodity * DxaccAccountGetCurrency(const Account *acc)
void gnc_account_foreach_descendant(const Account *acc, AccountCb thunk, gpointer user_data)
This method will traverse all children of this accounts and their descendants, calling 'func' on each...
void xaccAccountSetNotes(Account *acc, const char *str)
Set the account's notes.
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.
void gnc_account_delete_map_entry(Account *acc, char *head, char *category, char *match_string, gboolean empty)
Delete the entry for Account pointed to by head,category and match_string, if empty is TRUE then use ...
gboolean xaccTransIsOpen(const Transaction *trans)
The xaccTransIsOpen() method returns TRUE if the transaction is open for editing. ...
a simple price database for gnucash
QofInstance * qof_collection_lookup_entity(const QofCollection *col, const GncGUID *guid)
Find the entity going only from its guid.
Expense accounts are used to denote expenses.
int safe_utf8_collate(const char *da, const char *db)
Collate two UTF-8 strings.
#define PINFO(format, args...)
Print an informational note.
const char * xaccAccountGetFilter(const Account *acc)
Get the account's filter.
gnc_numeric xaccSplitGetReconciledBalance(const Split *s)
Returns the reconciled-balance of this split.
GNCAccountType xaccAccountGetType(const Account *acc)
Returns the account's account type.
gboolean xaccSplitDestroy(Split *split)
Destructor.
void xaccAccountSetMark(Account *acc, short m)
Set a mark on the account.
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.
const char * xaccAccountGetCode(const Account *acc)
Get the account's accounting code.
gboolean xaccAccountGetAppendText(const Account *acc)
Get the "import-append-text" flag for an account.
void xaccAccountSetReconcileLastDate(Account *acc, time64 last_date)
DOCUMENT ME!
total_count and the token_count for a given account let us calculate the probability of a given accou...
Account * gnc_account_create_root(QofBook *book)
Create a new root level account.
void gnc_commodity_decrement_usage_count(gnc_commodity *cm)
Decrement a commodity's internal counter that tracks how many accounts are using that commodity...
void xaccAccountSetTaxRelated(Account *acc, gboolean tax_related)
DOCUMENT ME!
gboolean qof_instance_get_destroying(gconstpointer ptr)
Retrieve the flag that indicates whether or not this object is about to be destroyed.
All arguments are required to have the same denominator, that denominator is to be used in the output...
Mutual Fund accounts will typically be shown in registers which show three columns: price...
void gnc_features_set_used(QofBook *book, const gchar *feature)
Indicate that the current book uses the given feature.
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.
gboolean gnc_commodity_equal(const gnc_commodity *a, const gnc_commodity *b)
This routine returns TRUE if the two commodities are equal.
void xaccAccountSortSplits(Account *acc, gboolean force)
The xaccAccountSortSplits() routine will resort the account's splits if the sort is dirty...
void xaccAccountSetCode(Account *acc, const char *str)
Set the account's accounting code.
gpointer gnc_account_foreach_descendant_until(const Account *acc, AccountCb2 thunk, gpointer user_data)
This method will traverse all children of this accounts and their descendants, calling 'func' on each...
void gnc_account_set_policy(Account *acc, GNCPolicy *policy)
Set the account's lot order policy.
void xaccAccountSetReconcileLastInterval(Account *acc, int months, int days)
DOCUMENT ME!
gnc_numeric gnc_numeric_add(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Return a+b.
gboolean gnc_account_remove_split(Account *acc, Split *s)
Remove the given split from an account.
gnc_numeric xaccAccountGetBalanceAsOfDateInCurrency(Account *acc, time64 date, gnc_commodity *report_commodity, gboolean include_children)
This function gets the balance at the end of the given date in the desired commodity.
guint32 xaccAccountTypesValid(void)
Returns the bitmask of the account type enums that are valid.
gboolean gnc_numeric_zero_p(gnc_numeric a)
Returns 1 if the given gnc_numeric is 0 (zero), else returns 0.
const char * xaccAccountTypeEnumAsString(GNCAccountType type)
Conversion routines for the account types to/from strings that are used in persistent storage...
stop here; the following types just aren't ready for prime time
GList * gnc_account_list_name_violations(QofBook *book, const gchar *separator)
Runs through all the accounts and returns a list of account names that contain the provided separator...
void xaccAccountSetHigherBalanceLimit(Account *acc, gnc_numeric balance)
Set the higher balance limit for the account.
void xaccAccountInsertLot(Account *acc, GNCLot *lot)
The xaccAccountInsertLot() method will register the indicated lot with this account.
Transaction * xaccSplitGetParent(const Split *split)
Returns the parent transaction of the split.
API for Transactions and Splits (journal entries)
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...
int(* QofSortFunc)(gconstpointer, gconstpointer)
This function is the default sort function for a particular object type.
int gnc_numeric_compare(gnc_numeric a, gnc_numeric b)
Returns 1 if a>b, -1 if b>a, 0 if a == b.
#define QOF_OBJECT_VERSION
Defines the version of the core object object registration interface.
gchar * gnc_numeric_to_string(gnc_numeric n)
Convert to string.
void xaccAccountMoveAllSplits(Account *accfrom, Account *accto)
The xaccAccountMoveAllSplits() routine reassigns each of the splits in accfrom to accto...
gboolean qof_commit_edit(QofInstance *inst)
commit_edit helpers
#define PERR(format, args...)
Log a serious error.
void gnc_account_set_sort_dirty(Account *acc)
Tell the account believes that the splits may be incorrectly sorted and need to be resorted...
#define ENTER(format, args...)
Print a function entry debugging message.
gnc_numeric gnc_pricedb_convert_balance_nearest_before_price_t64(GNCPriceDB *pdb, gnc_numeric balance, const gnc_commodity *balance_currency, const gnc_commodity *new_currency, time64 t)
Convert a balance from one currency to another using the price nearest to before the given time...
The cash account type is used to denote a shoe-box or pillowcase stuffed with * cash.
const char * gnc_account_get_debit_string(GNCAccountType acct_type)
Get the debit string associated with this account type.
void gnc_account_imap_add_account_bayes(Account *acc, GList *tokens, Account *added_acc)
Updates the imap for a given account using a list of tokens.
gnc_numeric xaccSplitGetBalance(const Split *s)
Returns the running balance up to and including the indicated split.
#define QOF_PARAM_BOOK
"Known" Object Parameters – all objects must support these
void xaccAccountSetLastNum(Account *acc, const char *num)
Set the last num field of an Account.
const char * qof_string_cache_insert(const char *key)
You can use this function with g_hash_table_insert(), for the key (or value), as long as you use the ...
gnc_numeric xaccAccountGetClearedBalance(const Account *acc)
Get the current balance of the account, only including cleared transactions.
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.
gnc_numeric gnc_pricedb_convert_balance_latest_price(GNCPriceDB *pdb, gnc_numeric balance, const gnc_commodity *balance_currency, const gnc_commodity *new_currency)
Convert a balance from one currency to another using the most recent price between the two...
gboolean xaccAccountGetReconcilePostponeDate(const Account *acc, time64 *postpone_date)
DOCUMENT ME!
intermediate values used to calculate the bayes probability of a given account where p(AB) = (a*b)/[a...
Account used to record multiple commodity transactions.
gboolean xaccAccountGetLowerBalanceLimit(const Account *acc, gnc_numeric *balance)
Get the lower balance limit for the account.
void xaccAccountDestroy(Account *acc)
The xaccAccountDestroy() routine can be used to get rid of an account.
gboolean xaccAccountIsHidden(const Account *acc)
Should this account be "hidden".
gboolean xaccSplitEqual(const Split *sa, const Split *sb, gboolean check_guids, gboolean check_balances, gboolean check_txn_splits)
Equality.
Account * gnc_account_lookup_by_name(const Account *parent, const char *name)
The gnc_account_lookup_by_name() subroutine fetches the account by name from the descendants of the s...
#define PWARN(format, args...)
Log a warning.
void gnc_account_remove_child(Account *parent, Account *child)
This function will remove the specified child account from the specified parent account.
int xaccAccountOrder(const Account *aa, const Account *ab)
The xaccAccountOrder() subroutine defines a sorting order on accounts.
Stock accounts will typically be shown in registers which show three columns: price, number of shares, and value.
const char * xaccAccountGetColor(const Account *acc)
Get the account's color.
Split * xaccAccountFindSplitByDesc(const Account *acc, const char *description)
Returns a pointer to the split, not a copy.
void qof_instance_init_data(QofInstance *inst, QofIdType type, QofBook *book)
Initialise the settings associated with an instance.
gboolean qof_begin_edit(QofInstance *inst)
begin_edit
#define xaccAccountGetGUID(X)
gboolean xaccAccountIsAssetLiabType(GNCAccountType t)
Convenience function to check if the account is a valid Asset or Liability type, but not a business a...
void xaccClearMarkDown(Account *acc, short val)
The xaccClearMarkDown will clear the mark only in this and in sub-accounts.
GList SplitList
GList of Split.
GNCAccountType xaccAccountStringToEnum(const char *str)
Conversion routines for the account types to/from strings that are used in persistent storage...
bank account type – don't use this for now, see NUM_ACCOUNT_TYPES
void xaccSplitSetAmount(Split *split, gnc_numeric amt)
The xaccSplitSetAmount() method sets the amount in the account's commodity that the split should have...
gchar * gnc_account_get_full_name(const Account *account)
The gnc_account_get_full_name routine returns the fully qualified name of the account using the given...
gnc_numeric xaccAccountGetReconciledBalanceAsOfDate(Account *acc, time64 date)
Get the reconciled balance of the account at the end of the day of the date specified.
void xaccAccountSetPlaceholder(Account *acc, gboolean val)
Set the "placeholder" flag for an account.
gboolean xaccAccountTypesCompatible(GNCAccountType parent_type, GNCAccountType child_type)
Return TRUE if accounts of type parent_type can have accounts of type child_type as children...
gnc_numeric xaccAccountGetNoclosingBalanceAsOfDateInCurrency(Account *acc, time64 date, gnc_commodity *report_commodity, gboolean include_children)
This function gets the balance at the end of the given date, ignoring closing entries, in the desired commodity.
gchar * gnc_account_name_violations_errmsg(const gchar *separator, GList *invalid_account_names)
Composes a translatable error message showing which account names clash with the current account sepa...
void xaccAccountClearLowerBalanceLimit(Account *acc)
Clear the lower balance limit for the account.
gboolean xaccTransactionTraverse(Transaction *trans, int stage)
xaccTransactionTraverse() checks the stage of the given transaction.
void xaccAccountSetColor(Account *acc, const char *str)
Set the account's Color.
Transaction * xaccAccountFindTransByDesc(const Account *acc, const char *description)
Returns a pointer to the transaction, not a copy.
void xaccAccountSetIncludeSubAccountBalances(Account *acc, gboolean inc_sub)
Set whether to include balances of sub accounts.
void gnc_account_set_balance_dirty(Account *acc)
Tell the account that the running balances may be incorrect and need to be recomputed.
Income accounts are used to denote income.
void gnc_account_foreach_child(const Account *acc, AccountCb thunk, gpointer user_data)
This method will traverse the immediate children of this accounts, calling 'func' on each account...
Account public routines (C++ api)
#define YREC
The Split has been reconciled.
Account * gnc_account_lookup_by_code(const Account *parent, const char *code)
The gnc_account_lookup_by_code() subroutine works like gnc_account_lookup_by_name, but uses the account code.
void gnc_account_tree_begin_staged_transaction_traversals(Account *account)
gnc_account_tree_begin_staged_transaction_traversals() resets the traversal marker inside every trans...
void dxaccAccountSetPriceSrc(Account *acc, const char *src)
Set a string that identifies the Finance::Quote backend that should be used to retrieve online prices...
#define GUID_ENCODING_LENGTH
Number of characters needed to encode a guid as a string not including the null terminator.
void xaccAccountBeginStagedTransactionTraversals(const Account *account)
xaccAccountBeginStagedTransactionTraversals() resets the traversal marker for each transaction which ...
void gnc_commodity_increment_usage_count(gnc_commodity *cm)
Increment a commodity's internal counter that tracks how many accounts are using that commodity...
#define FREC
frozen into accounting period
GNCPlaceholderType xaccAccountGetDescendantPlaceholder(const Account *acc)
Returns PLACEHOLDER_NONE if account is NULL or neither account nor any descendant of account is a pla...
const char * xaccAccountGetDescription(const Account *acc)
Get the account's description.
void gnc_account_set_start_reconciled_balance(Account *acc, const gnc_numeric start_baln)
This function will set the starting reconciled commodity balance for this account.
void gnc_account_delete_all_bayes_maps(Account *acc)
Delete all bayes entries for Account.
const char * dxaccAccountGetQuoteTZ(const Account *acc)
Get the timezone to be used when interpreting the results from a given Finance::Quote backend...
line of credit – don't use this for now, see NUM_ACCOUNT_TYPES
void xaccAccountClearReconcilePostpone(Account *acc)
DOCUMENT ME!
const char * xaccAccountGetTaxUSPayerNameSource(const Account *acc)
DOCUMENT ME!
gnc_numeric xaccSplitGetNoclosingBalance(const Split *s)
The noclosing-balance is the currency-denominated balance of all transactions except 'closing' transa...
gint null_strcmp(const gchar *da, const gchar *db)
The null_strcmp compares strings a and b the same way that strcmp() does, except that either may be n...
void gnc_account_reset_convert_bayes_to_flat(void)
Reset the flag that indicates the function imap_convert_bayes_to_flat has been run.
GList * gnc_account_get_children_sorted(const Account *account)
This routine returns a GList of all children accounts of the specified account, ordered by xaccAccoun...
The bank account type denotes a savings or checking account held at a bank.
LotList * xaccAccountGetLotList(const Account *acc)
The xaccAccountGetLotList() routine returns a list of all lots in this account.
void xaccAccountRecomputeBalance(Account *acc)
The following recompute the partial balances (stored with the transaction) and the total balance...
GList * gnc_account_imap_get_info_bayes(Account *acc)
Returns a GList of structure imap_info of all Bayesian mappings for required Account.
GList * gnc_account_imap_get_info(Account *acc, const char *category)
Returns a GList of structure imap_info of all Non Bayesian mappings for required Account.
const char * xaccTransGetDescription(const Transaction *trans)
Gets the transaction Description.
Account * gnc_account_lookup_by_full_name(const Account *any_acc, const gchar *name)
The gnc_account_lookup_full_name() subroutine works like gnc_account_lookup_by_name, but uses fully-qualified names using the given separator.
gboolean gnc_account_get_defer_bal_computation(Account *acc)
Get the account's flag for deferred balance computation.
void xaccAccountSetReconcilePostponeDate(Account *acc, time64 postpone_date)
DOCUMENT ME!
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
gpointer(* QofAccessFunc)(gpointer object, const QofParam *param)
The QofAccessFunc defines an arbitrary function pointer for access functions.
const char * xaccAccountGetTaxUSCode(const Account *acc)
DOCUMENT ME!
gboolean xaccAccountIsAPARType(GNCAccountType t)
Convenience function to check if the account is a valid business account type (meaning an Accounts Pa...
void qof_collection_insert_entity(QofCollection *, QofInstance *)
Take entity, remove it from whatever collection its currently in, and place it in a new collection...
bank account type – don't use this for now, see NUM_ACCOUNT_TYPES
void qof_collection_mark_clean(QofCollection *)
reset value of dirty flag
gboolean xaccAccountStringToType(const char *str, GNCAccountType *type)
Conversion routines for the account types to/from strings that are used in persistent storage...
void xaccTransCommitEdit(Transaction *trans)
The xaccTransCommitEdit() method indicates that the changes to the transaction and its splits are com...
Additional event handling code.
void xaccAccountSetIsOpeningBalance(Account *acc, gboolean val)
Set the "opening-balance" flag for an account.
void xaccAccountSetReconcilePostponeBalance(Account *acc, gnc_numeric balance)
DOCUMENT ME!
gboolean xaccAccountEqual(const Account *aa, const Account *ab, gboolean check_guids)
Compare two accounts for equality - this is a deep compare.
gboolean xaccAccountGetTaxRelated(const Account *acc)
DOCUMENT ME!
void gnc_account_set_start_cleared_balance(Account *acc, const gnc_numeric start_baln)
This function will set the starting cleared commodity balance for this account.
Account * xaccCloneAccount(const Account *from, QofBook *book)
The xaccCloneAccount() routine makes a simple copy of the indicated account, placing it in the indica...
void xaccTransBeginEdit(Transaction *trans)
The xaccTransBeginEdit() method must be called before any changes are made to a transaction or any of...
gnc_numeric xaccAccountGetReconciledBalance(const Account *acc)
Get the current balance of the account, only including reconciled transactions.
asset (and liability) accounts indicate generic, generalized accounts that are none of the above...
gint gnc_account_n_children(const Account *account)
Return the number of children of the specified account.
void gnc_account_join_children(Account *to_parent, Account *from_parent)
The gnc_account_join_children() subroutine will move (reparent) all child accounts from the from_pare...
gnc_numeric xaccAccountGetBalanceAsOfDate(Account *acc, time64 date)
Get the balance of the account at the end of the day before the date specified.
gnc_numeric xaccAccountGetBalance(const Account *acc)
Get the current balance of the account, which may include future splits.
gboolean xaccAccountGetReconcileLastDate(const Account *acc, time64 *last_date)
DOCUMENT ME!
void dxaccAccountSetQuoteTZ(Account *acc, const char *tz)
Set the timezone to be used when interpreting the results from a given Finance::Quote backend...
The currency account type indicates that the account is a currency trading account.
void xaccAccountSetCommoditySCU(Account *acc, int scu)
Set the SCU for the account.
gboolean qof_instance_books_equal(gconstpointer ptr1, gconstpointer ptr2)
See if two QofInstances share the same book.
GNCAccountType
The account types are used to determine how the transaction data in the account is displayed...
gnc_commodity * gnc_account_get_currency_or_parent(const Account *account)
Returns a gnc_commodity that is a currency, suitable for being a Transaction's currency.
Account * xaccAccountGetAssociatedAccount(const Account *acc, const char *tag)
Get the account's associated account e.g.
gboolean xaccAccountGetHidden(const Account *acc)
Get the "hidden" flag for an account.
void xaccAccountSetAppendText(Account *acc, gboolean val)
Set the "import-append-text" flag for an account.
Generic api to store and retrieve preferences.
gnc_numeric gnc_numeric_sub(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Return a-b.
gboolean gnc_account_insert_split(Account *acc, Split *s)
Insert the given split from an account.
GList * gnc_account_get_descendants(const Account *account)
This routine returns a flat list of all of the accounts that are descendants of the specified account...
void xaccAccountSetAutoInterest(Account *acc, gboolean val)
Set the "auto interest" flag for an account.
void xaccAccountSetTaxUSCode(Account *acc, const char *code)
DOCUMENT ME!
GNCPlaceholderType
DOCUMENT ME!
gboolean xaccAccountGetIsOpeningBalance(const Account *acc)
Get the "opening-balance" flag for an account.
guint32 xaccParentAccountTypesCompatibleWith(GNCAccountType type)
Return the bitmask of parent account types compatible with a given type.
gboolean xaccAccountGetReconcileChildrenStatus(const Account *acc)
DOCUMENT ME!
gboolean xaccAccountGetReconcileLastInterval(const Account *acc, int *months, int *days)
DOCUMENT ME!
gboolean xaccAccountGetIncludeSubAccountBalances(const Account *acc)
Get whether to include balances of sub accounts.
const char * dxaccAccountGetPriceSrc(const Account *acc)
Get a string that identifies the Finance::Quote backend that should be used to retrieve online prices...
liability (and asset) accounts indicate generic, generalized accounts that are none of the above...
const char * gnc_account_get_credit_string(GNCAccountType acct_type)
Get the credit string associated with this account type.
gboolean gnc_lot_is_closed(GNCLot *lot)
The gnc_lot_is_closed() routine returns a boolean flag: is this lot closed? A lot is closed if its ba...
GList * gnc_account_get_children(const Account *account)
This routine returns a GList of all children accounts of the specified account.
Split * gnc_account_find_split(const Account *acc, std::function< bool(const Split *)> predicate, bool reverse)
scans account split list (in forward or reverse order) until predicate split->bool returns true...
void xaccAccountSetHidden(Account *acc, gboolean val)
Set the "hidden" flag for an account.
void xaccAccountBeginEdit(Account *acc)
The xaccAccountBeginEdit() subroutine is the first phase of a two-phase-commit wrapper for account up...
gboolean xaccAccountHasAncestor(const Account *acc, const Account *ancestor)
Returns true if the account is 'ancestor' or has 'ancestor' as an ancestor.
Account * xaccSplitGetAccount(const Split *split)
Returns the account of this split, which was set through xaccAccountInsertSplit().
gchar * guid_to_string(const GncGUID *guid)
The guid_to_string() routine returns a null-terminated string encoding of the id. ...
gnc_commodity * xaccAccountGetCommodity(const Account *acc)
Get the account's commodity.
gboolean xaccTransGetIsClosingTxn(const Transaction *trans)
Returns whether this transaction is a "closing transaction".
gint qof_instance_guid_compare(gconstpointer ptr1, gconstpointer ptr2)
Compare the GncGUID values of two instances.
gboolean xaccAccountGetPlaceholder(const Account *acc)
Get the "placeholder" flag for an account.
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...
gint gnc_account_get_current_depth(const Account *account)
Return the number of levels of this account below the root account.
gboolean gnc_prefs_get_bool(const gchar *group, const gchar *pref_name)
Get a boolean value from the preferences backend.
void xaccAccountSetSortReversed(Account *acc, gboolean sortreversed)
Set the account's Sort Order direction.
bank account type – don't use this for now, see NUM_ACCOUNT_TYPES
#define LEAVE(format, args...)
Print a function exit debugging message.
Account * xaccAccountGainsAccount(Account *acc, gnc_commodity *curr)
Retrieve the gains account used by this account for the indicated currency, creating and recording a ...
void xaccAccountSetLowerBalanceLimit(Account *acc, gnc_numeric balance)
Set the lower balance limit for the account.
const char * gnc_commodity_get_unique_name(const gnc_commodity *cm)
Retrieve the 'unique' name for the specified commodity.
gboolean xaccAccountGetHigherBalanceLimit(const Account *acc, gnc_numeric *balance)
Get the higher balance limit for the account.
Round to the nearest integer, rounding away from zero when there are two equidistant nearest integers...
Account * gnc_account_nth_child(const Account *parent, gint num)
Return the n'th child account of the specified parent account.
Account * xaccMallocAccount(QofBook *book)
Constructor.
gint gnc_account_child_index(const Account *parent, const Account *child)
Return the index of the specified child within the list of the parent's children. ...
GNCNumericErrorCode gnc_numeric_check(gnc_numeric in)
Check for error signal in value.
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...
void xaccAccountSetTaxUSPayerNameSource(Account *acc, const char *source)
DOCUMENT ME!
Account * gnc_lot_get_account(const GNCLot *lot)
The gnc_lot_get_account() routine returns the account with which this lot is associated.
gboolean qof_object_register(const QofObject *object)
Register new types of object objects.
void xaccAccountSetDescription(Account *acc, const char *str)
Set the account's description.
void DxaccAccountSetCurrency(Account *acc, gnc_commodity *currency)
gpointer qof_collection_get_data(const QofCollection *col)
Store and retrieve arbitrary object-defined data.
void gnc_account_set_start_balance(Account *acc, const gnc_numeric start_baln)
This function will set the starting commodity balance for this account.
void xaccAccountSetNonStdSCU(Account *acc, gboolean flag)
Set the flag indicating that this account uses a non-standard SCU.
LotList * xaccAccountFindOpenLots(const Account *acc, gboolean(*match_func)(GNCLot *lot, gpointer user_data), gpointer user_data, GCompareFunc sort_func)
Find a list of open lots that match the match_func.
Account * gnc_account_get_root(Account *acc)
This routine returns the root account of the account tree that the specified account belongs to...
Account * gnc_account_lookup_by_opening_balance(Account *account, gnc_commodity *commodity)
Find the opening balance account for the currency.
void xaccAccountClearHigherBalanceLimit(Account *acc)
Clear the higher balance limit for the account.
void gnc_account_set_defer_bal_computation(Account *acc, gboolean defer)
Set the defer balance flag.
gboolean qof_book_shutting_down(const QofBook *book)
Is the book shutting down?
const char * xaccAccountGetName(const Account *acc)
Get the account's name.
Equity account is used to balance the balance sheet.
void qof_event_gen(QofInstance *entity, QofEventId event_id, gpointer event_data)
Invoke all registered event handlers using the given arguments.
const char * xaccAccountGetTypeStr(GNCAccountType type)
The xaccAccountGetTypeStr() routine returns a string suitable for use in the GUI/Interface.
#define GNC_EVENT_ITEM_ADDED
These events are used when a split is added to an account.
const char * xaccAccountGetSortOrder(const Account *acc)
Get the account's Sort Order.
#define GNC_DENOM_AUTO
Values that can be passed as the 'denom' argument.
API for Transactions and Splits (journal entries)
The type used to store guids in C.
int xaccAccountStagedTransactionTraversal(const Account *acc, unsigned int stage, TransactionCallback thunk, void *cb_data)
xaccAccountStagedTransactionTraversal() calls thunk on each transaction in account a whose current ma...
void xaccAccountCommitEdit(Account *acc)
ThexaccAccountCommitEdit() subroutine is the second phase of a two-phase-commit wrapper for account u...
void xaccClearMark(Account *acc, short val)
Get the mark set by xaccAccountSetMark short xaccAccountGetMark (const Account *account);.
void xaccAccountSetName(Account *acc, const char *str)
Set the account's name.
The hidden root account of an account tree.
gnc_commodity * gnc_commodity_obtain_twin(const gnc_commodity *from, QofBook *book)
Given the commodity 'findlike', this routine will find and return the equivalent commodity (commodity...
GNCPolicy * gnc_account_get_policy(Account *acc)
Get the account's lot order policy.
void qof_string_cache_remove(const char *key)
You can use this function as a destroy notifier for a GHashTable that uses common strings as keys (or...
gboolean gnc_commodity_equiv(const gnc_commodity *a, const gnc_commodity *b)
This routine returns TRUE if the two commodities are equivalent.
void gnc_account_merge_children(Account *parent)
The gnc_account_merge_children() subroutine will go through an account, merging all child accounts th...
gboolean xaccAccountIsEquityType(GNCAccountType t)
Convenience function to check if the account is a valid Equity type.
void xaccAccountSetReconcileChildrenStatus(Account *acc, gboolean status)
DOCUMENT ME!
The Credit card account is used to denote credit (e.g.
const gchar * gnc_get_account_separator_string(void)
Returns the account separation character chosen by the user.
void xaccAccountSetCommodity(Account *acc, gnc_commodity *com)
Set the account's commodity.
#define NREC
not reconciled or cleared
gnc_numeric xaccSplitGetAmount(const Split *split)
Returns the amount of the split in the account's commodity.
GList * gnc_account_lookup_by_type_and_commodity(Account *root, const char *name, GNCAccountType acctype, gnc_commodity *commodity)
Find a direct child account matching name, GNCAccountType, and/or commodity.
const char * xaccAccountGetNotes(const Account *acc)
Get the account's notes.
gboolean xaccAccountGetReconcilePostponeBalance(const Account *acc, gnc_numeric *balance)
DOCUMENT ME!
gint gnc_account_get_tree_depth(const Account *account)
Return the number of levels of descendants accounts below the specified account.
GNCPolicy * xaccGetFIFOPolicy(void)
First-in, First-out Policy This policy will create FIFO Lots.
Utility functions for file access.
Account * gnc_account_imap_find_account_bayes(Account *acc, GList *tokens)
Look up an Account in the map.
Account * xaccAccountLookup(const GncGUID *guid, QofBook *book)
The xaccAccountLookup() subroutine will return the account associated with the given id...
void xaccAccountSetTaxUSCopyNumber(Account *acc, gint64 copy_number)
DOCUMENT ME!