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 const 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);
1575 qof_collection_foreach(col, destroy_pending_splits_for_account, acc);
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))
2008 if (s == priv->splits.back())
2009 priv->splits.pop_back();
2011 priv->splits.erase (std::remove (priv->splits.begin(), priv->splits.end(), s),
2012 priv->splits.end());
2019 priv->balance_dirty = TRUE;
2029 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2031 priv = GET_PRIVATE(acc);
2032 if (!priv->sort_dirty || (!force && qof_instance_get_editlevel(acc) > 0))
2034 std::sort (priv->splits.begin(), priv->splits.end(), split_cmp_less);
2035 priv->sort_dirty = FALSE;
2036 priv->balance_dirty = TRUE;
2040 xaccAccountBringUpToDate(
Account *acc)
2056 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2057 g_return_if_fail(guid);
2060 PINFO(
"acct=%p", acc);
2062 qof_instance_set_guid (&acc->inst, guid);
2063 qof_instance_set_dirty(&acc->inst);
2074 if (!guid || !book)
return nullptr;
2087 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2089 priv = GET_PRIVATE(acc);
2098 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2110 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2112 priv = GET_PRIVATE(acc);
2114 for (node = priv->children; node; node = node->next)
2126 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
2128 return GET_PRIVATE(acc)->policy;
2136 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2138 priv = GET_PRIVATE(acc);
2146 xaccAccountRemoveLot (
Account *acc, GNCLot *lot)
2150 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2151 g_return_if_fail(GNC_IS_LOT(lot));
2153 priv = GET_PRIVATE(acc);
2154 g_return_if_fail(priv->lots);
2156 ENTER (
"(acc=%p, lot=%p)", acc, lot);
2157 priv->lots = g_list_remove(priv->lots, lot);
2158 qof_event_gen (QOF_INSTANCE(lot), QOF_EVENT_REMOVE,
nullptr);
2160 LEAVE (
"(acc=%p, lot=%p)", acc, lot);
2171 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2172 g_return_if_fail(GNC_IS_LOT(lot));
2176 if (lot_account == acc)
2179 ENTER (
"(acc=%p, lot=%p)", acc, lot);
2184 old_acc = lot_account;
2185 opriv = GET_PRIVATE(old_acc);
2186 opriv->lots = g_list_remove(opriv->lots, lot);
2189 priv = GET_PRIVATE(acc);
2190 priv->lots = g_list_prepend(priv->lots, lot);
2191 gnc_lot_set_account(lot, acc);
2201 LEAVE (
"(acc=%p, lot=%p)", acc, lot);
2207 xaccPreSplitMove (Split *split)
2213 xaccPostSplitMove (Split *split,
Account *accto)
2217 xaccSplitSetAccount(split, accto);
2229 g_return_if_fail(GNC_IS_ACCOUNT(accfrom));
2230 g_return_if_fail(GNC_IS_ACCOUNT(accto));
2233 from_priv = GET_PRIVATE(accfrom);
2234 if (from_priv->splits.empty() || accfrom == accto)
2239 ENTER (
"(accfrom=%p, accto=%p)", accfrom, accto);
2244 std::for_each (from_priv->splits.begin(), from_priv->splits.end(), xaccPreSplitMove);
2261 auto splits = from_priv->splits;
2262 std::for_each (splits.begin(), splits.end(), [accto](
auto s){ xaccPostSplitMove (s, accto); });
2265 g_assert(from_priv->splits.empty());
2266 g_assert(from_priv->lots ==
nullptr);
2270 LEAVE (
"(accfrom=%p, accto=%p)", accfrom, accto);
2306 gnc_numeric balance;
2307 gnc_numeric noclosing_balance;
2308 gnc_numeric cleared_balance;
2309 gnc_numeric reconciled_balance;
2311 if (
nullptr == acc)
return;
2313 priv = GET_PRIVATE(acc);
2314 if (qof_instance_get_editlevel(acc) > 0)
return;
2315 if (!priv->balance_dirty || priv->defer_bal_computation)
return;
2319 balance = priv->starting_balance;
2320 noclosing_balance = priv->starting_noclosing_balance;
2321 cleared_balance = priv->starting_cleared_balance;
2322 reconciled_balance = priv->starting_reconciled_balance;
2324 PINFO (
"acct=%s starting baln=%" G_GINT64_FORMAT
"/%" G_GINT64_FORMAT,
2325 priv->accountName, balance.num, balance.denom);
2326 for (
auto split : priv->splits)
2330 balance = gnc_numeric_add_fixed(balance, amt);
2332 if (
NREC != split->reconciled)
2334 cleared_balance = gnc_numeric_add_fixed(cleared_balance, amt);
2337 if (
YREC == split->reconciled ||
2338 FREC == split->reconciled)
2340 reconciled_balance =
2341 gnc_numeric_add_fixed(reconciled_balance, amt);
2345 noclosing_balance = gnc_numeric_add_fixed(noclosing_balance, amt);
2347 split->balance = balance;
2348 split->noclosing_balance = noclosing_balance;
2349 split->cleared_balance = cleared_balance;
2350 split->reconciled_balance = reconciled_balance;
2354 priv->balance = balance;
2355 priv->noclosing_balance = noclosing_balance;
2356 priv->cleared_balance = cleared_balance;
2357 priv->reconciled_balance = reconciled_balance;
2358 priv->balance_dirty = FALSE;
2377 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
2385 const char *da, *db;
2388 if ( aa && !ab )
return -1;
2389 if ( !aa && ab )
return +1;
2390 if ( !aa && !ab )
return 0;
2392 priv_aa = GET_PRIVATE(aa);
2393 priv_ab = GET_PRIVATE(ab);
2396 da = priv_aa->accountCode;
2397 db = priv_ab->accountCode;
2400 result = g_strcmp0 (da, db);
2406 if (-1 == revorder[0])
2411 revorder [typeorder[i]] = i;
2420 if (ta < tb)
return -1;
2421 if (ta > tb)
return +1;
2424 da = priv_aa->accountName;
2425 db = priv_ab->accountName;
2449 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2453 priv = GET_PRIVATE(acc);
2454 if (priv->type == tip)
2459 priv->balance_dirty = TRUE;
2470 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2471 g_return_if_fail(str);
2474 priv = GET_PRIVATE(acc);
2475 if (g_strcmp0(str, priv->accountName) == 0)
2490 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2493 priv = GET_PRIVATE(acc);
2494 if (g_strcmp0(str, priv->accountCode) == 0)
2509 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2512 priv = GET_PRIVATE(acc);
2513 if (g_strcmp0(str, priv->description) == 0)
2523 set_kvp_string_path (
Account *acc, std::vector<std::string>
const & path,
2526 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2529 if (value && *value)
2531 GValue v = G_VALUE_INIT;
2532 g_value_init (&v, G_TYPE_STRING);
2533 g_value_set_static_string (&v, value);
2534 qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v, path);
2539 qof_instance_set_path_kvp (QOF_INSTANCE (acc),
nullptr, path);
2546 set_kvp_string_tag (
Account *acc,
const char *tag,
const char *value)
2548 set_kvp_string_path (acc, {tag}, value);
2552 get_kvp_string_path (
const Account *acc, std::vector<std::string>
const & path,
2556 if (acc ==
nullptr)
return nullptr;
2557 qof_instance_get_path_kvp (QOF_INSTANCE (acc), v, path);
2558 return G_VALUE_HOLDS_STRING (v) ? g_value_get_string (v) : nullptr;
2562 get_kvp_string_tag (
const Account *acc,
const char *tag, GValue *v)
2564 return get_kvp_string_path (acc, {tag}, v);
2570 set_kvp_string_tag (acc,
"color", str);
2576 set_kvp_string_tag (acc,
"filter", str);
2582 set_kvp_string_tag (acc,
"sort-order", str);
2588 set_kvp_string_tag (acc,
"sort-reversed", sortreversed ?
"true" :
nullptr);
2596 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2597 g_return_if_fail(GNC_IS_ACCOUNT(parent));
2599 parent_acc = GNC_ACCOUNT(parent);
2603 mark_account (parent_acc);
2612 set_kvp_string_tag (acc,
"notes", str);
2619 g_return_if_fail (GNC_IS_ACCOUNT(acc));
2620 g_return_if_fail (tag && *tag);
2622 std::vector<std::string> path = {
"associated-account", tag };
2628 if (GNC_IS_ACCOUNT(assoc_acct))
2630 GValue v = G_VALUE_INIT;
2631 g_value_init (&v, GNC_TYPE_GUID);
2633 qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v, path);
2637 qof_instance_set_path_kvp (QOF_INSTANCE (acc),
nullptr, path);
2649 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2650 g_return_if_fail(GNC_IS_COMMODITY(com));
2653 priv = GET_PRIVATE(acc);
2654 if (com == priv->commodity)
2659 priv->commodity = com;
2662 priv->non_standard_scu = FALSE;
2665 for (
auto s : priv->splits)
2674 priv->sort_dirty = TRUE;
2675 priv->balance_dirty = TRUE;
2692 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2694 priv = GET_PRIVATE(acc);
2696 priv->commodity_scu = scu;
2698 priv->non_standard_scu = TRUE;
2706 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0);
2707 return GET_PRIVATE(acc)->commodity_scu;
2715 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0);
2717 priv = GET_PRIVATE(acc);
2718 if (priv->non_standard_scu || !priv->commodity)
2719 return priv->commodity_scu;
2728 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2730 priv = GET_PRIVATE(acc);
2731 if (priv->non_standard_scu == flag)
2734 priv->non_standard_scu = flag;
2742 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0);
2743 return GET_PRIVATE(acc)->non_standard_scu;
2754 GValue v = G_VALUE_INIT;
2756 gnc_commodity *commodity;
2757 gnc_commodity_table *
table;
2759 if ((!acc) || (!currency))
return;
2760 g_value_init (&v, G_TYPE_STRING);
2761 g_value_set_static_string (&v, s);
2762 qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v, {
"old-currency"});
2768 commodity = gnc_commodity_table_lookup_unique (
table, s);
2782 account_foreach_descendant (
const Account *acc, AccountCb thunk,
2783 void* user_data,
bool sort)
2787 g_return_if_fail (GNC_IS_ACCOUNT(acc));
2788 g_return_if_fail (thunk);
2790 auto priv{GET_PRIVATE(acc)};
2793 children = g_list_copy (priv->children);
2797 children = priv->children;
2799 for (
auto node = children; node; node = node->next)
2801 auto child =
static_cast<Account*
>(node->data);
2802 thunk (child, user_data);
2803 account_foreach_descendant (child, thunk, user_data, sort);
2807 g_list_free (children);
2818 g_assert(GNC_IS_ACCOUNT(new_parent));
2819 g_assert(GNC_IS_ACCOUNT(child));
2822 ppriv = GET_PRIVATE(new_parent);
2823 cpriv = GET_PRIVATE(child);
2824 old_parent = cpriv->parent;
2825 if (old_parent == new_parent)
2847 PWARN (
"reparenting accounts across books is not correctly supported\n");
2856 cpriv->parent = new_parent;
2857 ppriv->children = g_list_append(ppriv->children, child);
2858 qof_instance_set_dirty(&new_parent->inst);
2859 qof_instance_set_dirty(&child->inst);
2882 if (!parent)
return;
2884 ppriv = GET_PRIVATE(parent);
2885 cpriv = GET_PRIVATE(child);
2887 if (cpriv->parent != parent)
2889 PERR (
"account not a child of parent");
2895 ed.idx = g_list_index(ppriv->children, child);
2897 ppriv->children = g_list_remove(ppriv->children, child);
2903 cpriv->parent =
nullptr;
2911 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
2912 return GET_PRIVATE(acc)->parent;
2920 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
2922 priv = GET_PRIVATE(acc);
2923 while (priv->parent)
2926 priv = GET_PRIVATE(acc);
2935 g_return_val_if_fail(GNC_IS_ACCOUNT(account), FALSE);
2936 return (GET_PRIVATE(account)->parent ==
nullptr);
2942 g_return_val_if_fail(GNC_IS_ACCOUNT(account),
nullptr);
2943 return g_list_copy(GET_PRIVATE(account)->children);
2952 g_return_val_if_fail(GNC_IS_ACCOUNT(account),
nullptr);
2955 priv = GET_PRIVATE(account);
2956 if (!priv->children)
2958 return g_list_sort(g_list_copy(priv->children), (GCompareFunc)
xaccAccountOrder);
2964 g_return_val_if_fail(GNC_IS_ACCOUNT(account), 0);
2965 return g_list_length(GET_PRIVATE(account)->children);
2971 g_return_val_if_fail(GNC_IS_ACCOUNT(parent), -1);
2972 g_return_val_if_fail(GNC_IS_ACCOUNT(child), -1);
2973 return g_list_index(GET_PRIVATE(parent)->children, child);
2979 g_return_val_if_fail(GNC_IS_ACCOUNT(parent),
nullptr);
2980 return static_cast<Account*
>(g_list_nth_data(GET_PRIVATE(parent)->children, num));
2984 count_acct (
Account *account, gpointer user_data)
2986 auto count {
static_cast<int*
>(user_data)};
2994 account_foreach_descendant (account, count_acct, &count, FALSE);
3004 g_return_val_if_fail(GNC_IS_ACCOUNT(account), 0);
3006 priv = GET_PRIVATE(account);
3009 account = priv->parent;
3010 priv = GET_PRIVATE(account);
3022 gint depth = 0, child_depth;
3024 g_return_val_if_fail(GNC_IS_ACCOUNT(account), 0);
3026 priv = GET_PRIVATE(account);
3027 if (!priv->children)
3030 for (node = priv->children; node; node = g_list_next(node))
3033 depth = MAX(depth, child_depth);
3039 collect_acct (
Account *account, gpointer user_data)
3041 auto listptr{
static_cast<GList**
>(user_data)};
3042 *listptr = g_list_prepend (*listptr, account);
3048 GList* list =
nullptr;
3049 account_foreach_descendant (account, collect_acct, &list, FALSE);
3050 return g_list_reverse (list);
3056 GList* list =
nullptr;
3057 account_foreach_descendant (account, collect_acct, &list, TRUE);
3058 return g_list_reverse (list);
3067 account_foreach_descendant_breadthfirst_until (
const Account *acc,
3071 gpointer result {
nullptr};
3073 g_return_val_if_fail (GNC_IS_ACCOUNT(acc),
nullptr);
3074 g_return_val_if_fail (thunk,
nullptr);
3076 for (
auto node = GET_PRIVATE(acc)->children; !result && node; node = node->next)
3077 result = thunk (static_cast<Account*>(node->data), user_data);
3079 for (
auto node = GET_PRIVATE(acc)->children; !result && node; node = node->next)
3080 result = account_foreach_descendant_breadthfirst_until (static_cast<Account*>(node->data), thunk, user_data);
3086 is_acct_name (
Account *account, gpointer user_data)
3088 auto name {
static_cast<gchar*
>(user_data)};
3095 return (
Account*)account_foreach_descendant_breadthfirst_until (parent, is_acct_name, (
char*)name);
3099 is_acct_code (
Account *account, gpointer user_data)
3101 auto name {
static_cast<gchar*
>(user_data)};
3108 return (
Account*)account_foreach_descendant_breadthfirst_until (parent, is_acct_code, (
char*)code);
3112 is_opening_balance_account (
Account* account, gpointer data)
3114 gnc_commodity* commodity = GNC_COMMODITY(data);
3131 gnc_account_lookup_by_full_name_helper (
const Account *parent,
3138 g_return_val_if_fail(GNC_IS_ACCOUNT(parent),
nullptr);
3139 g_return_val_if_fail(names,
nullptr);
3142 ppriv = GET_PRIVATE(parent);
3143 for (node = ppriv->children; node; node = node->next)
3147 priv = GET_PRIVATE(account);
3148 if (g_strcmp0(priv->accountName, names[0]) == 0)
3152 if (names[1] ==
nullptr)
3156 if (!priv->children)
3160 found = gnc_account_lookup_by_full_name_helper(account, &names[1]);
3161 if (found !=
nullptr)
3181 g_return_val_if_fail(GNC_IS_ACCOUNT(any_acc),
nullptr);
3182 g_return_val_if_fail(name,
nullptr);
3185 rpriv = GET_PRIVATE(root);
3186 while (rpriv->parent)
3188 root = rpriv->parent;
3189 rpriv = GET_PRIVATE(root);
3192 found = gnc_account_lookup_by_full_name_helper(root, names);
3201 gnc_commodity* commodity)
3204 auto rpriv{GET_PRIVATE(root)};
3205 for (
auto node = rpriv->children; node; node = node->next)
3207 auto account{
static_cast<Account*
>(node->data)};
3218 retval = g_list_prepend(retval, account);
3223 for (
auto node = rpriv->children; node; node = node->next)
3225 auto account{
static_cast<Account*
>(node->data)};
3231 retval = g_list_concat(result, retval);
3244 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3245 g_return_if_fail(thunk);
3247 priv = GET_PRIVATE(acc);
3248 for (node = priv->children; node; node = node->next)
3250 thunk (static_cast<Account*>(node->data), user_data);
3259 account_foreach_descendant (acc, thunk, user_data, FALSE);
3267 gpointer result {
nullptr};
3269 g_return_val_if_fail (GNC_IS_ACCOUNT(acc),
nullptr);
3270 g_return_val_if_fail (thunk,
nullptr);
3272 auto priv{GET_PRIVATE(acc)};
3274 for (
auto node = priv->children; node; node = node->next)
3276 auto child =
static_cast<Account*
>(node->data);
3277 result = thunk (child, user_data);
3292 return GET_PRIVATE(acc)->type;
3296 qofAccountGetTypeString (
const Account *acc)
3298 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3303 qofAccountSetType (
Account *acc,
const char *type_string)
3305 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3306 g_return_if_fail(type_string);
3313 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3314 return GET_PRIVATE(acc)->accountName;
3323 const gchar **names;
3328 if (
nullptr == account)
3329 return g_strdup(
"");
3332 g_return_val_if_fail(GNC_IS_ACCOUNT(account), g_strdup(
""));
3335 priv = GET_PRIVATE(account);
3337 return g_strdup(
"");
3342 for (a = account; a; a = priv->parent)
3344 priv = GET_PRIVATE(a);
3350 names = (
const gchar **)g_malloc(level *
sizeof(gchar *));
3351 names[--level] =
nullptr;
3352 for (a = account; level > 0; a = priv->parent)
3354 priv = GET_PRIVATE(a);
3355 names[--level] = priv->accountName;
3359 fullname = g_strjoinv(account_separator, (gchar **)names);
3368 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3369 return GET_PRIVATE(acc)->accountCode;
3375 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3376 return GET_PRIVATE(acc)->description;
3382 GValue v = G_VALUE_INIT;
3383 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3384 auto rv = get_kvp_string_tag (acc,
"color", &v);
3392 GValue v = G_VALUE_INIT;
3393 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0);
3394 auto rv = get_kvp_string_tag (acc,
"filter", &v);
3402 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0);
3403 GValue v = G_VALUE_INIT;
3404 auto rv = get_kvp_string_tag (acc,
"sort-order", &v);
3412 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
3413 GValue v = G_VALUE_INIT;
3414 auto rv = !g_strcmp0 (get_kvp_string_tag (acc,
"sort-reversed", &v),
"true");
3422 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3423 GValue v = G_VALUE_INIT;
3424 auto rv = get_kvp_string_tag (acc,
"notes", &v);
3432 g_return_val_if_fail (GNC_IS_ACCOUNT(acc),
nullptr);
3433 g_return_val_if_fail (tag && *tag,
nullptr);
3435 GValue v = G_VALUE_INIT;
3436 qof_instance_get_path_kvp (QOF_INSTANCE (acc), &v, {
"associated-account", tag });
3438 auto guid =
static_cast<GncGUID*
>(G_VALUE_HOLDS_BOXED (&v) ? g_value_get_boxed(&v) :
nullptr);
3454 GValue v = G_VALUE_INIT;
3455 const char *s =
nullptr;
3456 gnc_commodity_table *
table;
3457 gnc_commodity *retval =
nullptr;
3459 if (!acc)
return nullptr;
3460 qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, {
"old-currency"});
3461 if (G_VALUE_HOLDS_STRING (&v))
3462 s = g_value_get_string (&v);
3466 retval = gnc_commodity_table_lookup_unique (
table, s);
3476 if (!GNC_IS_ACCOUNT(acc))
3478 return GET_PRIVATE(acc)->commodity;
3483 gnc_commodity * commodity;
3484 g_return_val_if_fail (account,
nullptr);
3491 const Account *parent_account = account;
3509 while (parent_account);
3521 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3523 priv = GET_PRIVATE(acc);
3524 priv->starting_balance = start_baln;
3525 priv->balance_dirty = TRUE;
3530 const gnc_numeric start_baln)
3534 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3536 priv = GET_PRIVATE(acc);
3537 priv->starting_cleared_balance = start_baln;
3538 priv->balance_dirty = TRUE;
3543 const gnc_numeric start_baln)
3547 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3549 priv = GET_PRIVATE(acc);
3550 priv->starting_reconciled_balance = start_baln;
3551 priv->balance_dirty = TRUE;
3557 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3558 return GET_PRIVATE(acc)->balance;
3564 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3565 return GET_PRIVATE(acc)->cleared_balance;
3571 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3572 return GET_PRIVATE(acc)->reconciled_balance;
3576 xaccAccountGetProjectedMinimumBalance (
const Account *acc)
3579 std::optional<gnc_numeric> minimum;
3581 auto before_today_end = [&minimum, today](
const Split *s) ->
bool 3591 return minimum ? *minimum : gnc_numeric_zero();
3599 GetBalanceAsOfDate (
Account *acc,
time64 date, std::function<gnc_numeric(Split*)> split_to_numeric)
3601 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3606 auto is_before_date = [date](
auto s) ->
bool 3610 return latest_split ? split_to_numeric (latest_split) : gnc_numeric_zero();
3620 xaccAccountGetNoclosingBalanceAsOfDate (
Account *acc,
time64 date)
3635 xaccAccountGetPresentBalance (
const Account *acc)
3637 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3654 xaccAccountConvertBalanceToCurrency(
const Account *acc,
3655 gnc_numeric balance,
3656 const gnc_commodity *balance_currency,
3657 const gnc_commodity *new_currency)
3666 book = gnc_account_get_book (acc);
3670 pdb, balance, balance_currency, new_currency);
3680 xaccAccountConvertBalanceToCurrencyAsOfDate(
const Account *acc,
3681 gnc_numeric balance,
3682 const gnc_commodity *balance_currency,
3683 const gnc_commodity *new_currency,
3693 book = gnc_account_get_book (acc);
3697 pdb, balance, balance_currency, new_currency, date);
3708 xaccAccountGetXxxBalanceInCurrency (
const Account *acc,
3709 xaccGetBalanceFn fn,
3710 const gnc_commodity *report_currency)
3713 gnc_numeric balance;
3715 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3716 g_return_val_if_fail(fn, gnc_numeric_zero());
3717 g_return_val_if_fail(GNC_IS_COMMODITY(report_currency), gnc_numeric_zero());
3719 priv = GET_PRIVATE(acc);
3721 balance = xaccAccountConvertBalanceToCurrency(acc, balance,
3728 xaccAccountGetXxxBalanceAsOfDateInCurrency(
Account *acc,
time64 date,
3729 xaccGetBalanceAsOfDateFn fn,
3730 const gnc_commodity *report_commodity)
3734 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3735 g_return_val_if_fail(fn, gnc_numeric_zero());
3736 g_return_val_if_fail(GNC_IS_COMMODITY(report_commodity), gnc_numeric_zero());
3738 priv = GET_PRIVATE(acc);
3739 return xaccAccountConvertBalanceToCurrencyAsOfDate(
3740 acc, fn(acc, date), priv->commodity, report_commodity, date);
3748 const gnc_commodity *currency;
3749 gnc_numeric balance;
3750 xaccGetBalanceFn fn;
3751 xaccGetBalanceAsOfDateFn asOfDateFn;
3762 xaccAccountBalanceHelper (
Account *acc, gpointer data)
3765 gnc_numeric balance;
3767 if (!cb->fn || !cb->currency)
3769 balance = xaccAccountGetXxxBalanceInCurrency (acc, cb->fn, cb->currency);
3776 xaccAccountBalanceAsOfDateHelper (
Account *acc, gpointer data)
3779 gnc_numeric balance;
3781 g_return_if_fail (cb->asOfDateFn && cb->currency);
3783 balance = xaccAccountGetXxxBalanceAsOfDateInCurrency (
3784 acc, cb->date, cb->asOfDateFn, cb->currency);
3803 xaccAccountGetXxxBalanceInCurrencyRecursive (
const Account *acc,
3804 xaccGetBalanceFn fn,
3805 const gnc_commodity *report_commodity,
3806 gboolean include_children)
3808 gnc_numeric balance;
3810 if (!acc)
return gnc_numeric_zero ();
3811 if (!report_commodity)
3813 if (!report_commodity)
3814 return gnc_numeric_zero();
3816 balance = xaccAccountGetXxxBalanceInCurrency (acc, fn, report_commodity);
3820 if (include_children)
3827 cb.balance = balance;
3833 balance = cb.balance;
3840 xaccAccountGetXxxBalanceAsOfDateInCurrencyRecursive (
3842 const gnc_commodity *report_commodity, gboolean include_children)
3844 gnc_numeric balance;
3846 g_return_val_if_fail(acc, gnc_numeric_zero());
3847 if (!report_commodity)
3849 if (!report_commodity)
3850 return gnc_numeric_zero();
3852 balance = xaccAccountGetXxxBalanceAsOfDateInCurrency(
3853 acc, date, fn, report_commodity);
3857 if (include_children)
3864 cb.balance = balance;
3866 CurrencyBalance cb = { report_commodity, balance,
nullptr, fn, date };
3870 balance = cb.balance;
3877 xaccAccountGetBalanceInCurrency (
const Account *acc,
3878 const gnc_commodity *report_commodity,
3879 gboolean include_children)
3882 rc = xaccAccountGetXxxBalanceInCurrencyRecursive (
3884 PINFO(
" baln=%" G_GINT64_FORMAT
"/%" G_GINT64_FORMAT, rc.num, rc.denom);
3890 xaccAccountGetClearedBalanceInCurrency (
const Account *acc,
3891 const gnc_commodity *report_commodity,
3892 gboolean include_children)
3894 return xaccAccountGetXxxBalanceInCurrencyRecursive (
3900 xaccAccountGetReconciledBalanceInCurrency (
const Account *acc,
3901 const gnc_commodity *report_commodity,
3902 gboolean include_children)
3904 return xaccAccountGetXxxBalanceInCurrencyRecursive (
3910 xaccAccountGetPresentBalanceInCurrency (
const Account *acc,
3911 const gnc_commodity *report_commodity,
3912 gboolean include_children)
3914 return xaccAccountGetXxxBalanceAsOfDateInCurrencyRecursive (
3921 xaccAccountGetProjectedMinimumBalanceInCurrency (
3923 const gnc_commodity *report_commodity,
3924 gboolean include_children)
3926 return xaccAccountGetXxxBalanceInCurrencyRecursive (
3927 acc, xaccAccountGetProjectedMinimumBalance, report_commodity,
3934 gboolean include_children)
3936 return xaccAccountGetXxxBalanceAsOfDateInCurrencyRecursive (
3944 gboolean include_children)
3946 return xaccAccountGetXxxBalanceAsOfDateInCurrencyRecursive
3947 (acc, date, xaccAccountGetNoclosingBalanceAsOfDate,
3948 report_commodity, include_children);
3963 xaccAccountGetNoclosingBalanceChangeForPeriod (
Account *acc,
time64 t1,
3964 time64 t2, gboolean recurse)
3975 const gnc_commodity *currency;
3976 gnc_numeric balanceChange;
3982 xaccAccountBalanceChangeHelper (
Account *acc, gpointer data)
3990 gnc_numeric balanceChange_conv = xaccAccountConvertBalanceToCurrencyAsOfDate(acc, balanceChange,
xaccAccountGetCommodity(acc), cbdiff->currency, cbdiff->t2);
3991 cbdiff->balanceChange =
gnc_numeric_add (cbdiff->balanceChange, balanceChange_conv,
3997 xaccAccountGetNoclosingBalanceChangeInCurrencyForPeriod (
Account *acc,
time64 t1,
3998 time64 t2, gboolean recurse)
4013 balanceChange = cbdiff.balanceChange;
4015 return balanceChange;
4022 xaccAccountGetSplits (
const Account *account)
4024 return GNC_IS_ACCOUNT(account) ? GET_PRIVATE(account)->splits : SplitsVec{};
4030 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
4031 auto priv{GET_PRIVATE(acc)};
4032 return std::accumulate (priv->splits.rbegin(), priv->splits.rend(),
4033 static_cast<GList*
>(
nullptr), g_list_prepend);
4037 xaccAccountGetSplitsSize (
const Account *account)
4039 return GNC_IS_ACCOUNT(account) ? GET_PRIVATE(account)->splits.size() : 0;
4042 gboolean gnc_account_and_descendants_empty (
Account *acc)
4044 g_return_val_if_fail (GNC_IS_ACCOUNT (acc), FALSE);
4045 auto priv = GET_PRIVATE (acc);
4046 if (!priv->splits.empty())
return FALSE;
4047 for (
auto *n = priv->children; n; n = n->next)
4049 if (!gnc_account_and_descendants_empty (static_cast<Account*>(n->data)))
4058 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
4059 return g_list_copy(GET_PRIVATE(acc)->lots);
4064 gboolean (*match_func)(GNCLot *lot,
4065 gpointer user_data),
4066 gpointer user_data, GCompareFunc sort_func)
4070 GList *retval =
nullptr;
4072 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
4074 priv = GET_PRIVATE(acc);
4075 for (lot_list = priv->lots; lot_list; lot_list = lot_list->next)
4077 GNCLot *lot =
static_cast<GNCLot*
>(lot_list->data);
4083 if (match_func && !(match_func)(lot, user_data))
4087 retval = g_list_prepend (retval, lot);
4091 retval = g_list_sort (retval, sort_func);
4098 gpointer (*proc)(GNCLot *lot,
void *data),
void *data)
4102 gpointer result =
nullptr;
4104 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
4105 g_return_val_if_fail(proc,
nullptr);
4107 priv = GET_PRIVATE(acc);
4108 for (node = priv->lots; node; node = node->next)
4109 if ((result = proc((GNCLot *)node->data, data)))
4116 set_boolean_key (
Account *acc, std::vector<std::string>
const & path, gboolean option)
4118 GValue v = G_VALUE_INIT;
4119 g_return_if_fail(GNC_IS_ACCOUNT(acc));
4121 g_value_init (&v, G_TYPE_BOOLEAN);
4122 g_value_set_boolean (&v, option);
4124 qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v, path);
4131 boolean_from_key (
const Account *acc, std::vector<std::string>
const & path)
4133 GValue v = G_VALUE_INIT;
4134 gboolean retval = FALSE;
4135 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4136 qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, path);
4137 if (G_VALUE_HOLDS_INT64 (&v))
4138 retval = (g_value_get_int64 (&v) != 0);
4139 if (G_VALUE_HOLDS_BOOLEAN (&v))
4140 retval = (g_value_get_boolean (&v));
4141 if (G_VALUE_HOLDS_STRING (&v))
4142 retval = !strcmp (g_value_get_string (&v),
"true");
4154 return boolean_from_key(acc, {
"tax-related"});
4160 set_boolean_key(acc, {
"tax-related"}, tax_related);
4166 GValue v = G_VALUE_INIT;
4167 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4168 qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, {
"tax-US",
"code"});
4169 return G_VALUE_HOLDS_STRING (&v) ? g_value_get_string (&v) :
nullptr;
4175 set_kvp_string_path (acc, {
"tax-US",
"code"}, code);
4181 GValue v = G_VALUE_INIT;
4182 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4183 qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, {
"tax-US",
"payer-name-source"});
4184 return G_VALUE_HOLDS_STRING (&v) ? g_value_get_string (&v) :
nullptr;
4190 set_kvp_string_path (acc, {
"tax-US",
"payer-name-source"}, source);
4196 gint64 copy_number = 0;
4197 GValue v = G_VALUE_INIT;
4198 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4199 qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, {
"tax-US",
"copy-number"});
4200 if (G_VALUE_HOLDS_INT64 (&v))
4201 copy_number = g_value_get_int64 (&v);
4204 return (copy_number == 0) ? 1 : copy_number;
4210 g_return_if_fail(GNC_IS_ACCOUNT(acc));
4212 if (copy_number != 0)
4214 GValue v = G_VALUE_INIT;
4215 g_value_init (&v, G_TYPE_INT64);
4216 g_value_set_int64 (&v, copy_number);
4217 qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v, {
"tax-US",
"copy-number"});
4222 qof_instance_set_path_kvp (QOF_INSTANCE (acc),
nullptr, {
"tax-US",
"copy-number"});
4235 return _(dflt_acct_debit_str);
4237 auto result = gnc_acct_debit_strs.find(acct_type);
4238 if (result != gnc_acct_debit_strs.end())
4239 return _(result->second);
4241 return _(dflt_acct_debit_str);
4247 return _(dflt_acct_credit_str);
4249 auto result = gnc_acct_credit_strs.find(acct_type);
4250 if (result != gnc_acct_credit_strs.end())
4251 return _(result->second);
4253 return _(dflt_acct_credit_str);
4262 return boolean_from_key(acc, {
"placeholder"});
4268 set_boolean_key(acc, {
"placeholder"}, val);
4274 return boolean_from_key(acc, {
"import-append-text"});
4280 set_boolean_key(acc, {
"import-append-text"}, val);
4289 GValue v = G_VALUE_INIT;
4290 auto rv = !g_strcmp0 (get_kvp_string_tag (acc,
"equity-type", &v),
4301 set_kvp_string_tag(acc,
"equity-type", val ?
"opening-balance" :
nullptr);
4307 GList *descendants, *node;
4310 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), PLACEHOLDER_NONE);
4314 for (node = descendants; node; node = node->next)
4317 ret = PLACEHOLDER_CHILD;
4321 g_list_free(descendants);
4331 return boolean_from_key (acc, {KEY_RECONCILE_INFO,
"auto-interest-transfer"});
4337 set_boolean_key (acc, {KEY_RECONCILE_INFO,
"auto-interest-transfer"}, val);
4346 return boolean_from_key (acc, {
"hidden"});
4352 set_boolean_key (acc, {
"hidden"}, val);
4360 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4364 priv = GET_PRIVATE(acc);
4365 while ((acc = priv->parent) !=
nullptr)
4367 priv = GET_PRIVATE(acc);
4382 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4383 g_return_val_if_fail(GNC_IS_ACCOUNT(ancestor), FALSE);
4386 while (parent && parent != ancestor)
4387 parent = GET_PRIVATE(parent)->parent;
4389 return (parent == ancestor);
4398 #define GNC_RETURN_ENUM_AS_STRING(x) case (ACCT_TYPE_ ## x): return #x; 4405 GNC_RETURN_ENUM_AS_STRING(NONE);
4406 GNC_RETURN_ENUM_AS_STRING(BANK);
4407 GNC_RETURN_ENUM_AS_STRING(CASH);
4408 GNC_RETURN_ENUM_AS_STRING(CREDIT);
4409 GNC_RETURN_ENUM_AS_STRING(ASSET);
4410 GNC_RETURN_ENUM_AS_STRING(LIABILITY);
4411 GNC_RETURN_ENUM_AS_STRING(STOCK);
4412 GNC_RETURN_ENUM_AS_STRING(MUTUAL);
4413 GNC_RETURN_ENUM_AS_STRING(CURRENCY);
4414 GNC_RETURN_ENUM_AS_STRING(INCOME);
4415 GNC_RETURN_ENUM_AS_STRING(EXPENSE);
4416 GNC_RETURN_ENUM_AS_STRING(EQUITY);
4417 GNC_RETURN_ENUM_AS_STRING(RECEIVABLE);
4418 GNC_RETURN_ENUM_AS_STRING(PAYABLE);
4419 GNC_RETURN_ENUM_AS_STRING(ROOT);
4420 GNC_RETURN_ENUM_AS_STRING(TRADING);
4421 GNC_RETURN_ENUM_AS_STRING(CHECKING);
4422 GNC_RETURN_ENUM_AS_STRING(SAVINGS);
4423 GNC_RETURN_ENUM_AS_STRING(MONEYMRKT);
4424 GNC_RETURN_ENUM_AS_STRING(CREDITLINE);
4426 PERR (
"asked to translate unknown account type %d.\n", type);
4432 #undef GNC_RETURN_ENUM_AS_STRING 4434 #define GNC_RETURN_ON_MATCH(x) \ 4435 if(g_strcmp0(#x, (str)) == 0) { *type = ACCT_TYPE_ ## x; return(TRUE); } 4441 GNC_RETURN_ON_MATCH(NONE);
4442 GNC_RETURN_ON_MATCH(BANK);
4443 GNC_RETURN_ON_MATCH(CASH);
4444 GNC_RETURN_ON_MATCH(CREDIT);
4445 GNC_RETURN_ON_MATCH(ASSET);
4446 GNC_RETURN_ON_MATCH(LIABILITY);
4447 GNC_RETURN_ON_MATCH(STOCK);
4448 GNC_RETURN_ON_MATCH(MUTUAL);
4449 GNC_RETURN_ON_MATCH(CURRENCY);
4450 GNC_RETURN_ON_MATCH(INCOME);
4451 GNC_RETURN_ON_MATCH(EXPENSE);
4452 GNC_RETURN_ON_MATCH(EQUITY);
4453 GNC_RETURN_ON_MATCH(RECEIVABLE);
4454 GNC_RETURN_ON_MATCH(PAYABLE);
4455 GNC_RETURN_ON_MATCH(ROOT);
4456 GNC_RETURN_ON_MATCH(TRADING);
4457 GNC_RETURN_ON_MATCH(CHECKING);
4458 GNC_RETURN_ON_MATCH(SAVINGS);
4459 GNC_RETURN_ON_MATCH(MONEYMRKT);
4460 GNC_RETURN_ON_MATCH(CREDITLINE);
4462 PERR(
"asked to translate unknown account type string %s.\n",
4463 str ? str :
"(null)");
4468 #undef GNC_RETURN_ON_MATCH 4514 return _(account_type_name [type]);
4556 PERR(
"bad account type: %d", type);
4602 PERR(
"bad account type: %d", type);
4709 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4711 priv = GET_PRIVATE(acc);
4723 GValue v = G_VALUE_INIT;
4724 gboolean retval = FALSE;
4725 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4726 qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, {KEY_RECONCILE_INFO,
"last-date"});
4727 if (G_VALUE_HOLDS_INT64 (&v))
4728 date = g_value_get_int64 (&v);
4747 GValue v = G_VALUE_INIT;
4748 g_return_if_fail(GNC_IS_ACCOUNT(acc));
4750 g_value_init (&v, G_TYPE_INT64);
4751 g_value_set_int64 (&v, last_date);
4753 qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v, {KEY_RECONCILE_INFO,
"last-date"});
4764 int *months,
int *days)
4766 GValue v1 = G_VALUE_INIT, v2 = G_VALUE_INIT;
4767 int64_t m = 0, d = 0;
4768 gboolean retval = FALSE;
4770 if (!acc)
return FALSE;
4771 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4772 qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v1,
4773 {KEY_RECONCILE_INFO,
"last-interval",
"months"});
4774 qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v2,
4775 {KEY_RECONCILE_INFO,
"last-interval",
"days"});
4776 if (G_VALUE_HOLDS_INT64 (&v1))
4777 m = g_value_get_int64 (&v1);
4778 if (G_VALUE_HOLDS_INT64 (&v2))
4779 d = g_value_get_int64 (&v2);
4788 g_value_unset (&v1);
4789 g_value_unset (&v2);
4799 GValue v1 = G_VALUE_INIT, v2 = G_VALUE_INIT;
4800 g_return_if_fail(GNC_IS_ACCOUNT(acc));
4802 g_value_init (&v1, G_TYPE_INT64);
4803 g_value_set_int64 (&v1, months);
4804 g_value_init (&v2, G_TYPE_INT64);
4805 g_value_set_int64 (&v2, days);
4807 qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v1,
4808 {KEY_RECONCILE_INFO,
"last-interval",
"months"});
4809 qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v2,
4810 {KEY_RECONCILE_INFO,
"last-interval",
"days"});
4813 g_value_unset (&v1);
4814 g_value_unset (&v2);
4824 gboolean retval = FALSE;
4825 GValue v = G_VALUE_INIT;
4826 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4827 qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v,
4828 {KEY_RECONCILE_INFO, KEY_POSTPONE,
"date"});
4829 if (G_VALUE_HOLDS_INT64 (&v))
4830 date = g_value_get_int64 (&v);
4835 *postpone_date = date;
4848 GValue v = G_VALUE_INIT;
4849 g_return_if_fail(GNC_IS_ACCOUNT(acc));
4851 g_value_init (&v, G_TYPE_INT64);
4852 g_value_set_int64 (&v, postpone_date);
4854 qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v,
4855 {KEY_RECONCILE_INFO, KEY_POSTPONE,
"date"});
4866 gnc_numeric *balance)
4868 gnc_numeric bal = gnc_numeric_zero ();
4869 GValue v = G_VALUE_INIT;
4870 gboolean retval = FALSE;
4871 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4872 qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v,
4873 {KEY_RECONCILE_INFO, KEY_POSTPONE,
"balance"});
4874 if (G_VALUE_HOLDS_BOXED (&v))
4876 bal = *(gnc_numeric*)g_value_get_boxed (&v);
4894 GValue v = G_VALUE_INIT;
4895 g_return_if_fail(GNC_IS_ACCOUNT(acc));
4897 g_value_init (&v, GNC_TYPE_NUMERIC);
4898 g_value_set_boxed (&v, &balance);
4900 qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v,
4901 {KEY_RECONCILE_INFO, KEY_POSTPONE,
"balance"});
4917 qof_instance_set_path_kvp (QOF_INSTANCE(acc),
nullptr, {KEY_RECONCILE_INFO, KEY_POSTPONE});
4928 GValue v = G_VALUE_INIT;
4929 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4930 qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, {
"last-num"});
4931 return G_VALUE_HOLDS_STRING (&v) ? g_value_get_string (&v) :
nullptr;
4940 GValue v = G_VALUE_INIT;
4941 g_return_if_fail(GNC_IS_ACCOUNT(acc));
4942 g_value_init (&v, G_TYPE_STRING);
4944 g_value_set_static_string (&v, num);
4946 qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v, {
"last-num"});
4957 gnc_numeric *balance)
4959 g_return_val_if_fail (GNC_IS_ACCOUNT(acc),
false);
4961 if (GET_PRIVATE(acc)->higher_balance_limit.has_value())
4963 *balance = GET_PRIVATE(acc)->higher_balance_limit.value();
4972 gnc_numeric bal = gnc_numeric_create (1,0);
4973 GValue v = G_VALUE_INIT;
4974 gboolean retval =
false;
4976 qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, {KEY_BALANCE_LIMIT,
4977 KEY_BALANCE_HIGHER_LIMIT_VALUE});
4978 if (G_VALUE_HOLDS_BOXED(&v))
4980 bal = *(gnc_numeric*)g_value_get_boxed (&v);
4990 GET_PRIVATE(acc)->higher_balance_limit = bal;
4997 gnc_numeric *balance)
4999 g_return_val_if_fail (GNC_IS_ACCOUNT(acc),
false);
5001 if (GET_PRIVATE(acc)->lower_balance_limit.has_value())
5003 *balance = GET_PRIVATE(acc)->lower_balance_limit.value();
5012 gnc_numeric bal = gnc_numeric_create (1,0);
5013 GValue v = G_VALUE_INIT;
5014 gboolean retval =
false;
5016 qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, {KEY_BALANCE_LIMIT,
5017 KEY_BALANCE_LOWER_LIMIT_VALUE});
5018 if (G_VALUE_HOLDS_BOXED(&v))
5020 bal = *(gnc_numeric*)g_value_get_boxed (&v);
5030 GET_PRIVATE(acc)->lower_balance_limit = bal;
5037 set_balance_limits (
Account *acc, gnc_numeric balance, gboolean higher)
5039 gnc_numeric balance_limit;
5040 gboolean balance_limit_valid;
5041 std::vector<std::string> path {KEY_BALANCE_LIMIT};
5045 path.push_back (KEY_BALANCE_HIGHER_LIMIT_VALUE);
5050 path.push_back (KEY_BALANCE_LOWER_LIMIT_VALUE);
5056 GValue v = G_VALUE_INIT;
5057 g_value_init (&v, GNC_TYPE_NUMERIC);
5058 g_value_set_boxed (&v, &balance);
5061 qof_instance_set_path_kvp (QOF_INSTANCE(acc), &v, path);
5064 GET_PRIVATE(acc)->higher_balance_limit = balance;
5068 GET_PRIVATE(acc)->lower_balance_limit = balance;
5079 g_return_if_fail (GNC_IS_ACCOUNT(acc));
5084 set_balance_limits (acc, balance,
true);
5090 g_return_if_fail (GNC_IS_ACCOUNT(acc));
5095 set_balance_limits (acc, balance,
false);
5100 clear_balance_limits (
Account *acc, gboolean higher)
5102 gnc_numeric balance_limit;
5103 gboolean balance_limit_valid;
5104 std::vector<std::string> path {KEY_BALANCE_LIMIT};
5108 path.push_back (KEY_BALANCE_HIGHER_LIMIT_VALUE);
5113 path.push_back (KEY_BALANCE_LOWER_LIMIT_VALUE);
5117 if (balance_limit_valid)
5120 qof_instance_set_path_kvp (QOF_INSTANCE(acc),
nullptr, path);
5121 qof_instance_slot_path_delete_if_empty (QOF_INSTANCE(acc), {KEY_BALANCE_LIMIT});
5123 GET_PRIVATE(acc)->higher_balance_limit.reset();
5125 GET_PRIVATE(acc)->lower_balance_limit.reset();
5134 g_return_if_fail (GNC_IS_ACCOUNT(acc));
5136 clear_balance_limits (acc,
true);
5142 g_return_if_fail (GNC_IS_ACCOUNT(acc));
5144 clear_balance_limits (acc,
false);
5150 g_return_val_if_fail (GNC_IS_ACCOUNT(acc),
false);
5152 if (!GET_PRIVATE(acc)->include_sub_account_balances.has_value())
5154 gboolean inc_sub = boolean_from_key (acc, {KEY_BALANCE_LIMIT,
5155 KEY_BALANCE_INCLUDE_SUB_ACCTS});
5157 GET_PRIVATE(acc)->include_sub_account_balances = inc_sub;
5159 return GET_PRIVATE(acc)->include_sub_account_balances.value();
5165 g_return_if_fail (GNC_IS_ACCOUNT(acc));
5169 GValue v = G_VALUE_INIT;
5170 g_value_init (&v, G_TYPE_BOOLEAN);
5171 g_value_set_boolean (&v, inc_sub);
5172 std::vector<std::string> path {KEY_BALANCE_LIMIT,
5173 KEY_BALANCE_INCLUDE_SUB_ACCTS};
5176 qof_instance_set_path_kvp (QOF_INSTANCE(acc), &v, path);
5178 qof_instance_set_path_kvp (QOF_INSTANCE(acc),
nullptr, path);
5179 GET_PRIVATE(acc)->include_sub_account_balances = inc_sub;
5190 GetOrMakeOrphanAccount (
Account *root, gnc_commodity * currency)
5195 g_return_val_if_fail (root,
nullptr);
5200 PERR (
"No currency specified!");
5204 accname = g_strconcat (_(
"Orphaned Gains"),
"-",
5220 _(
"Realized Gains or Losses from " 5221 "Commodity or Trading Accounts " 5222 "that haven't been recorded elsewhere."));
5237 GValue v = G_VALUE_INIT;
5238 std::vector<std::string> path {KEY_LOT_MGMT,
"gains-acct",
5243 g_return_val_if_fail (acc !=
nullptr,
nullptr);
5244 qof_instance_get_path_kvp (QOF_INSTANCE(acc), &v, path);
5245 if (G_VALUE_HOLDS_BOXED (&v))
5246 guid = (
GncGUID*)g_value_get_boxed (&v);
5247 if (guid ==
nullptr)
5254 GValue vr = G_VALUE_INIT;
5255 g_value_init (&vr, GNC_TYPE_GUID);
5256 g_value_set_boxed (&vr, guid);
5257 qof_instance_set_path_kvp (QOF_INSTANCE (acc), &vr, path);
5258 qof_instance_set_dirty (QOF_INSTANCE (acc));
5259 g_value_unset (&vr);
5268 return gains_account;
5280 set_kvp_string_tag (acc,
"old-price-source", src);
5289 static char *source =
nullptr;
5290 if (!acc)
return nullptr;
5296 GValue v = G_VALUE_INIT;
5297 auto rv = get_kvp_string_tag (acc,
"old-price-source", &v);
5310 set_kvp_string_tag (acc,
"old-quote-tz", tz);
5319 if (!acc)
return nullptr;
5321 GValue v = G_VALUE_INIT;
5322 auto rv = get_kvp_string_tag (acc,
"old-quote-tz", &v);
5333 GValue v = G_VALUE_INIT;
5341 g_value_init (&v, G_TYPE_INT64);
5342 g_value_set_int64 (&v, status);
5343 qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v,
5344 {KEY_RECONCILE_INFO, KEY_INCLUDE_CHILDREN});
5360 GValue v = G_VALUE_INIT;
5362 if (!acc)
return FALSE;
5363 qof_instance_get_path_kvp (QOF_INSTANCE (acc), &v,
5364 {KEY_RECONCILE_INFO, KEY_INCLUDE_CHILDREN});
5365 retval = G_VALUE_HOLDS_INT64 (&v) ? g_value_get_int64 (&v) : FALSE;
5376 auto has_description = [description](
const Split* s) ->
bool 5400 GList *children, *node;
5403 g_return_if_fail(GNC_IS_ACCOUNT(to_parent));
5404 g_return_if_fail(GNC_IS_ACCOUNT(from_parent));
5407 from_priv = GET_PRIVATE(from_parent);
5408 if (!from_priv->children)
5412 children = g_list_copy(from_priv->children);
5413 for (node = children; node; node = g_list_next(node))
5415 g_list_free(children);
5425 GList *node_a, *node_b, *work, *worker;
5427 g_return_if_fail(GNC_IS_ACCOUNT(parent));
5429 ppriv = GET_PRIVATE(parent);
5430 for (node_a = ppriv->children; node_a; node_a = node_a->next)
5434 priv_a = GET_PRIVATE(acc_a);
5435 for (node_b = node_a->next; node_b; node_b = g_list_next(node_b))
5439 priv_b = GET_PRIVATE(acc_b);
5440 if (0 !=
null_strcmp(priv_a->accountName, priv_b->accountName))
5442 if (0 !=
null_strcmp(priv_a->accountCode, priv_b->accountCode))
5444 if (0 !=
null_strcmp(priv_a->description, priv_b->description))
5454 if (priv_a->type != priv_b->type)
5458 if (priv_b->children)
5460 work = g_list_copy(priv_b->children);
5461 for (worker = work; worker; worker = g_list_next(worker))
5473 while (!priv_b->splits.empty())
5474 xaccSplitSetAccount (priv_b->splits.front(), acc_a);
5478 node_b = g_list_previous(node_b);
5493 xaccSplitsBeginStagedTransactionTraversals (SplitsVec& splits)
5495 for (
auto s : splits)
5497 Transaction *trans = s->parent;
5510 xaccSplitsBeginStagedTransactionTraversals(GET_PRIVATE (account)->splits);
5516 if (trans ==
nullptr)
return FALSE;
5518 if (trans->marker < stage)
5520 trans->marker = stage;
5527 static void do_one_account (
Account *account, gpointer data)
5530 std::for_each (priv->splits.begin(), priv->splits.end(),
5531 [](
auto s){ s->parent->marker = 0; });
5541 g_list_foreach(descendants, (GFunc)do_one_account,
nullptr);
5542 g_list_free(descendants);
5548 TransactionCallback thunk,
5554 auto splits = GET_PRIVATE(acc)->splits;
5555 for (
auto s : splits)
5557 auto trans = s->parent;
5558 if (trans && (trans->marker < stage))
5560 trans->marker = stage;
5563 auto retval = thunk(trans, cb_data);
5564 if (retval)
return retval;
5575 TransactionCallback thunk,
5585 priv = GET_PRIVATE(acc);
5586 for (
auto acc_p = priv->children; acc_p; acc_p = g_list_next(acc_p))
5589 stage, thunk, cb_data);
5590 if (retval)
return retval;
5594 for (
auto s : priv->splits)
5597 if (trans && (trans->marker < stage))
5599 trans->marker = stage;
5602 retval = thunk(trans, cb_data);
5603 if (retval)
return retval;
5616 int (*proc)(Transaction *t,
void *data),
5619 if (!acc || !proc)
return 0;
5630 if (!acc || !proc)
return 0;
5641 #define IMAP_FRAME "import-map" 5642 #define IMAP_FRAME_BAYES "import-map-bayes" 5646 gnc_account_imap_find_account (
Account *acc,
5647 const char *category,
5650 GValue v = G_VALUE_INIT;
5653 if (!acc || !key)
return nullptr;
5654 std::vector<std::string> path {IMAP_FRAME};
5656 path.push_back (category);
5657 path.push_back (key);
5658 qof_instance_get_path_kvp (QOF_INSTANCE (acc), &v, path);
5659 if (G_VALUE_HOLDS_BOXED (&v))
5660 guid = (
GncGUID*)g_value_get_boxed (&v);
5667 gnc_account_imap_find_any (QofBook *book,
const char* category,
const char *key)
5672 auto root = gnc_book_get_root_account (book);
5676 for (
auto ptr = accts; ptr; ptr = g_list_next (ptr))
5678 auto tmp_acc =
static_cast<Account*
> (ptr->data);
5680 if (gnc_account_imap_find_account (tmp_acc, category, key))
5686 g_list_free (accts);
5693 gnc_account_imap_add_account (
Account *acc,
5694 const char *category,
5698 GValue v = G_VALUE_INIT;
5699 if (!acc || !key || !added_acc || (strlen (key) == 0))
return;
5700 std::vector<std::string> path {IMAP_FRAME};
5702 path.emplace_back (category);
5703 path.emplace_back (key);
5704 g_value_init (&v, GNC_TYPE_GUID);
5707 qof_instance_set_path_kvp (QOF_INSTANCE (acc), &v, path);
5708 qof_instance_set_dirty (QOF_INSTANCE (acc));
5715 gnc_account_imap_delete_account (
Account *acc,
5716 const char *category,
5719 if (!acc || !key)
return;
5720 std::vector<std::string> path {IMAP_FRAME};
5722 path.emplace_back (category);
5723 path.emplace_back (key);
5725 if (qof_instance_has_path_slot (QOF_INSTANCE (acc), path))
5727 qof_instance_slot_path_delete (QOF_INSTANCE (acc), path);
5729 qof_instance_slot_path_delete_if_empty (QOF_INSTANCE (acc), {IMAP_FRAME, category});
5730 qof_instance_slot_path_delete_if_empty (QOF_INSTANCE (acc), {IMAP_FRAME});
5732 qof_instance_set_dirty (QOF_INSTANCE (acc));
5748 double product_difference;
5753 std::string account_guid;
5754 int64_t token_count;
5762 std::vector<AccountTokenCount> accounts;
5763 int64_t total_count;
5771 std::string account_guid;
5772 int32_t probability;
5776 build_token_info(
char const * suffix, KvpValue * value,
TokenAccountsInfo & tokenInfo)
5780 tokenInfo.total_count += value->get<int64_t>();
5782 tokenInfo.accounts.emplace_back(
AccountTokenCount{std::string{suffix}, value->get<int64_t>()});
5789 static constexpr
int probability_factor = 100000;
5791 static FinalProbabilityVec
5792 build_probabilities(ProbabilityVec
const & first_pass)
5794 FinalProbabilityVec ret;
5795 for (
auto const & first_pass_prob : first_pass)
5797 auto const & account_probability = first_pass_prob.second;
5802 int32_t probability = (account_probability.product /
5803 (account_probability.product + account_probability.product_difference)) * probability_factor;
5804 ret.push_back({first_pass_prob.first, probability});
5810 highest_probability(FinalProbabilityVec
const & probabilities)
5812 AccountInfo ret {
"", std::numeric_limits<int32_t>::min()};
5813 for (
auto const & prob : probabilities)
5814 if (prob.second > ret.probability)
5819 static ProbabilityVec
5820 get_first_pass_probabilities(
Account* acc, GList * tokens)
5825 for (
auto current_token = tokens; current_token; current_token = current_token->next)
5828 auto path = std::string{IMAP_FRAME_BAYES
"/"} + static_cast <
char const *> (current_token->data) +
"/";
5829 qof_instance_foreach_slot_prefix (QOF_INSTANCE (acc), path, &build_token_info, tokenInfo);
5830 for (
auto const & current_account_token : tokenInfo.accounts)
5832 auto item = std::find_if(ret.begin(), ret.end(), [¤t_account_token]
5833 (std::pair<std::string, AccountProbability>
const & a) {
5834 return current_account_token.account_guid == a.first;
5836 if (item != ret.end())
5838 item->second.product = ((double)current_account_token.token_count /
5839 (
double)tokenInfo.total_count) * item->second.product;
5840 item->second.product_difference = ((
double)1 - ((double)current_account_token.token_count /
5841 (
double)tokenInfo.total_count)) * item->second.product_difference;
5847 new_probability.product = ((double)current_account_token.token_count /
5848 (
double)tokenInfo.total_count);
5849 new_probability.product_difference = 1 - (new_probability.product);
5850 ret.push_back({current_account_token.account_guid, std::move(new_probability)});
5858 look_for_old_separator_descendants (
Account *root, std::string
const & full_name,
const gchar *separator)
5860 GList *top_accounts, *ptr;
5864 PINFO(
"Incoming full_name is '%s', current separator is '%s'", full_name.c_str (), separator);
5866 for (ptr = top_accounts; ptr; ptr = g_list_next (ptr))
5870 if (g_str_has_prefix (full_name.c_str (), name))
5872 gint name_len = strlen (name);
5873 const gchar old_sep = full_name[name_len];
5874 if (!g_ascii_isalnum (old_sep))
5876 if (name_len > found_len)
5878 found_sep = full_name[name_len];
5879 found_len = name_len;
5884 g_list_free (top_accounts);
5885 std::string new_name {full_name};
5887 std::replace (new_name.begin (), new_name.end (), found_sep, *separator);
5888 PINFO (
"Return full_name is '%s'", new_name.c_str ());
5893 get_guid_from_account_name (
Account * root, std::string
const & name)
5898 auto temp_account_name = look_for_old_separator_descendants (root, name,
5903 return temp_guid.to_string ();
5907 convert_entry (KvpEntry entry,
Account* root)
5910 auto account_name = entry.first.back();
5911 if (!gnc::GUID::is_valid_guid (account_name))
5917 entry.first.pop_back();
5918 auto guid_str = get_guid_from_account_name (root, account_name);
5919 entry.first.emplace_back (guid_str);
5921 std::string new_key {std::accumulate (entry.first.begin(), entry.first.end(), std::string {})};
5922 new_key = IMAP_FRAME_BAYES + new_key;
5923 return {new_key, entry.second};
5926 static std::vector<FlatKvpEntry>
5929 auto frame = qof_instance_get_slots (QOF_INSTANCE (acc));
5930 auto slot = frame->get_slot ({IMAP_FRAME_BAYES});
5933 auto imap_frame = slot->get<KvpFrame*> ();
5934 auto flat_kvp = imap_frame->flatten_kvp ();
5936 std::vector <FlatKvpEntry> ret;
5937 for (
auto const & flat_entry : flat_kvp)
5939 auto converted_entry = convert_entry (flat_entry, root);
5941 if (converted_entry.first.size())
5942 ret.emplace_back (converted_entry);
5948 convert_imap_account_bayes_to_flat (
Account *acc)
5950 auto frame = qof_instance_get_slots (QOF_INSTANCE (acc));
5951 if (!frame->get_keys().size())
5953 auto flat_imap = get_flat_imap(acc);
5954 if (!flat_imap.size ())
5957 frame->set({IMAP_FRAME_BAYES},
nullptr);
5958 std::for_each(flat_imap.begin(), flat_imap.end(),
5959 [&frame] (FlatKvpEntry
const & entry) {
5960 frame->set({entry.first.c_str()}, entry.second);
5962 qof_instance_set_dirty (QOF_INSTANCE (acc));
5971 imap_convert_bayes_to_flat (QofBook * book)
5973 auto root = gnc_book_get_root_account (book);
5976 for (
auto ptr = accts; ptr; ptr = g_list_next (ptr))
5979 if (convert_imap_account_bayes_to_flat (acc))
5985 g_list_free (accts);
5992 imap_convert_bayes_to_flat_run =
false;
6007 check_import_map_data (QofBook *book)
6009 if (gnc_features_check_used (book, GNC_FEATURE_GUID_FLAT_BAYESIAN) ||
6010 imap_convert_bayes_to_flat_run)
6014 imap_convert_bayes_to_flat (book);
6015 imap_convert_bayes_to_flat_run =
true;
6018 static constexpr
double threshold = .90 * probability_factor;
6026 auto book = gnc_account_get_book(acc);
6027 check_import_map_data (book);
6028 auto first_pass = get_first_pass_probabilities(acc, tokens);
6029 if (!first_pass.size())
6031 auto final_probabilities = build_probabilities(first_pass);
6032 if (!final_probabilities.size())
6034 auto best = highest_probability(final_probabilities);
6035 if (best.account_guid ==
"")
6037 if (best.probability < threshold)
6041 guid = gnc::GUID::from_string(best.account_guid);
6050 change_imap_entry (
Account *acc, std::string
const & path, int64_t token_count)
6052 GValue value = G_VALUE_INIT;
6054 PINFO(
"Source Account is '%s', Count is '%" G_GINT64_FORMAT
"'",
6058 if (qof_instance_has_slot (QOF_INSTANCE(acc), path.c_str ()))
6060 int64_t existing_token_count = 0;
6063 qof_instance_get_path_kvp (QOF_INSTANCE (acc), &value, {path});
6065 if (G_VALUE_HOLDS_INT64 (&value))
6066 existing_token_count = g_value_get_int64 (&value);
6068 PINFO(
"found existing value of '%" G_GINT64_FORMAT
"'", existing_token_count);
6070 token_count = token_count + existing_token_count;
6073 if (!G_IS_VALUE (&value))
6074 g_value_init (&value, G_TYPE_INT64);
6076 g_value_set_int64 (&value, token_count);
6079 qof_instance_set_path_kvp (QOF_INSTANCE (acc), &value, {path});
6081 g_value_unset (&value);
6090 GList *current_token;
6092 char *account_fullname;
6101 check_import_map_data (gnc_account_get_book(acc));
6103 g_return_if_fail (added_acc !=
nullptr);
6107 PINFO(
"account name: '%s'", account_fullname);
6112 for (current_token = g_list_first(tokens); current_token;
6113 current_token = current_token->next)
6119 if (!current_token->data || (*((
char*)current_token->data) ==
'\0'))
6123 PINFO(
"adding token '%s'", (
char*)current_token->data);
6124 auto path = std::string {IMAP_FRAME_BAYES} +
'/' +
static_cast<char*
>(current_token->data) +
'/' + guid_string;
6126 change_imap_entry (acc, path, token_count);
6129 qof_instance_set_dirty (QOF_INSTANCE (acc));
6131 g_free (account_fullname);
6132 g_free (guid_string);
6139 build_non_bayes (
const char *key,
const GValue *value, gpointer user_data)
6141 if (!G_VALUE_HOLDS_BOXED (value))
6145 gchar *guid_string =
nullptr;
6150 guid = (
GncGUID*)g_value_get_boxed (value);
6153 PINFO(
"build_non_bayes: match string '%s', match account guid: '%s'",
6154 (
char*)key, guid_string);
6158 imapInfo_node->source_account = imapInfo->source_account;
6160 imapInfo_node->head = g_strdup (imapInfo->head);
6161 imapInfo_node->match_string = g_strdup (key);
6162 imapInfo_node->category = g_strdup (imapInfo->category);
6163 imapInfo_node->count = g_strdup (
" ");
6165 imapInfo->list = g_list_prepend (imapInfo->list, imapInfo_node);
6167 g_free (guid_string);
6171 build_bayes (
const char *suffix, KvpValue * value,
GncImapInfo & imapInfo)
6174 std::string account_guid {&suffix[guid_start]};
6178 guid = gnc::GUID::from_string (account_guid);
6182 PWARN(
"Invalid GUID string from %s%s", IMAP_FRAME_BAYES, suffix);
6184 auto map_account =
xaccAccountLookup (&guid, gnc_account_get_book (imapInfo.source_account));
6186 auto count = value->get <int64_t> ();
6187 imap_node->source_account = imapInfo.source_account;
6188 imap_node->map_account = map_account;
6189 imap_node->head = g_strdup_printf (
"%s%s", IMAP_FRAME_BAYES, suffix);
6190 imap_node->match_string = g_strndup (&suffix[1], guid_start - 2);
6191 imap_node->category = g_strdup(
" ");
6192 imap_node->count = g_strdup_printf (
"%" G_GINT64_FORMAT, count);
6193 imapInfo.list = g_list_prepend (imapInfo.list, imap_node);
6198 g_free (imapInfo->head);
6199 g_free (imapInfo->category);
6200 g_free (imapInfo->match_string);
6201 g_free (imapInfo->count);
6208 check_import_map_data (gnc_account_get_book (acc));
6212 qof_instance_foreach_slot_prefix (QOF_INSTANCE (acc), IMAP_FRAME_BAYES, &build_bayes, imapInfo);
6213 return g_list_reverse(imapInfo.list);
6219 GList *list =
nullptr;
6223 std::vector<std::string> path {IMAP_FRAME};
6225 path.emplace_back (category);
6227 imapInfo.source_account = acc;
6228 imapInfo.list = list;
6230 imapInfo.head = g_strdup (IMAP_FRAME);
6231 imapInfo.category = g_strdup (category);
6233 if (qof_instance_has_path_slot (QOF_INSTANCE (acc), path))
6235 qof_instance_foreach_slot (QOF_INSTANCE(acc), IMAP_FRAME, category,
6236 build_non_bayes, &imapInfo);
6238 g_free (imapInfo.head);
6239 g_free (imapInfo.category);
6240 return g_list_reverse(imapInfo.list);
6248 GValue v = G_VALUE_INIT;
6249 auto rv = g_strdup (category ?
6250 get_kvp_string_path (acc, {head, category}, &v) :
6251 get_kvp_string_path (acc, {head}, &v));
6259 char *match_string, gboolean empty)
6263 std::vector<std::string> path {head};
6265 path.emplace_back (category);
6267 path.emplace_back (match_string);
6269 if (qof_instance_has_path_slot (QOF_INSTANCE (acc), path))
6273 qof_instance_slot_path_delete_if_empty (QOF_INSTANCE(acc), path);
6275 qof_instance_slot_path_delete (QOF_INSTANCE(acc), path);
6276 PINFO(
"Account is '%s', head is '%s', category is '%s', match_string is'%s'",
6278 qof_instance_set_dirty (QOF_INSTANCE(acc));
6289 auto slots = qof_instance_get_slots_prefix (QOF_INSTANCE (acc), IMAP_FRAME_BAYES);
6290 if (!slots.size())
return;
6292 for (
auto const & entry : slots)
6294 qof_instance_slot_path_delete (QOF_INSTANCE (acc), {entry.first});
6296 qof_instance_set_dirty (QOF_INSTANCE(acc));
6305 destroy_all_child_accounts (
Account *acc, gpointer data)
6312 gnc_account_book_end(QofBook* book)
6314 Account *root_account = gnc_book_get_root_account (book);
6324 accounts = g_list_reverse (accounts);
6325 g_list_foreach (accounts, (GFunc)destroy_all_child_accounts,
nullptr);
6326 g_list_free (accounts);
6339 static QofObject account_object_def =
6342 DI(.e_type = ) GNC_ID_ACCOUNT,
6345 DI(.book_begin = )
nullptr,
6346 DI(.book_end = ) gnc_account_book_end,
6349 DI(.foreach = ) qof_collection_foreach,
6354 gboolean xaccAccountRegister (
void)
6356 static QofParam params[] =
6359 ACCOUNT_NAME_, QOF_TYPE_STRING,
6364 ACCOUNT_CODE_, QOF_TYPE_STRING,
6369 ACCOUNT_DESCRIPTION_, QOF_TYPE_STRING,
6374 ACCOUNT_COLOR_, QOF_TYPE_STRING,
6379 ACCOUNT_FILTER_, QOF_TYPE_STRING,
6384 ACCOUNT_SORT_ORDER_, QOF_TYPE_STRING,
6389 ACCOUNT_SORT_REVERSED_, QOF_TYPE_BOOLEAN,
6394 ACCOUNT_NOTES_, QOF_TYPE_STRING,
6399 ACCOUNT_PRESENT_, QOF_TYPE_NUMERIC,
6403 ACCOUNT_BALANCE_, QOF_TYPE_NUMERIC,
6407 ACCOUNT_CLEARED_, QOF_TYPE_NUMERIC,
6411 ACCOUNT_RECONCILED_, QOF_TYPE_NUMERIC,
6415 ACCOUNT_TYPE_, QOF_TYPE_STRING,
6420 ACCOUNT_FUTURE_MINIMUM_, QOF_TYPE_NUMERIC,
6421 (
QofAccessFunc) xaccAccountGetProjectedMinimumBalance,
nullptr 6424 ACCOUNT_TAX_RELATED, QOF_TYPE_BOOLEAN,
6429 ACCOUNT_OPENING_BALANCE_, QOF_TYPE_BOOLEAN,
6434 ACCOUNT_SCU, QOF_TYPE_INT32,
6439 ACCOUNT_NSCU, QOF_TYPE_BOOLEAN,
6444 ACCOUNT_PARENT, GNC_ID_ACCOUNT,
6453 QOF_PARAM_GUID, QOF_TYPE_GUID,
6464 using AccountSet = std::unordered_set<Account*>;
6465 static void maybe_add_descendants (
Account* acc, gpointer arg)
6467 g_return_if_fail (acc);
6469 if (static_cast <AccountSet*> (arg)->insert (acc).second)
6470 g_list_foreach (GET_PRIVATE(acc)->children, (GFunc) maybe_add_descendants, arg);
6474 gnc_accounts_and_all_descendants (GList *accounts)
6477 g_list_foreach (accounts, (GFunc) maybe_add_descendants, &accset);
6478 return std::accumulate (accset.begin(), accset.end(), (GList*)
nullptr, g_list_prepend);
6485 utest_account_get_private (
Account *acc)
6487 return GET_PRIVATE (acc);
6491 _utest_account_fill_functions(
void)
6495 func->get_private = utest_account_get_private;
6496 func->coll_get_root_account = gnc_coll_get_root_account;
6497 func->xaccFreeAccountChildren = xaccFreeAccountChildren;
6498 func->xaccFreeAccount = xaccFreeAccount;
6499 func->qofAccountSetParent = qofAccountSetParent;
6500 func->gnc_account_lookup_by_full_name_helper =
6501 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(* 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)
Returns closed status of the given lot.
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)
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!