31 #include <glib/gi18n.h> 40 #include "TransactionP.hpp" 46 #include "qofinstance-p.h" 52 #include <unordered_set> 55 static QofLogModule log_module = GNC_MOD_ACCOUNT;
58 static gchar account_separator[8] =
".";
59 static gunichar account_uc_separator =
':';
61 static bool imap_convert_bayes_to_flat_run =
false;
64 static const std::string KEY_ASSOC_INCOME_ACCOUNT(
"ofx/associated-income-account");
65 static const std::string KEY_RECONCILE_INFO(
"reconcile-info");
66 static const std::string KEY_INCLUDE_CHILDREN(
"include-children");
67 static const std::string KEY_POSTPONE(
"postpone");
68 static const std::string KEY_LOT_MGMT(
"lot-mgmt");
69 static const std::string KEY_ONLINE_ID(
"online_id");
70 static const std::string KEY_IMP_APPEND_TEXT(
"import-append-text");
71 static const std::string AB_KEY(
"hbci");
72 static const std::string AB_ACCOUNT_ID(
"account-id");
73 static const std::string AB_ACCOUNT_UID(
"account-uid");
74 static const std::string AB_BANK_CODE(
"bank-code");
75 static const std::string AB_TRANS_RETRIEVAL(
"trans-retrieval");
77 static const std::string KEY_BALANCE_LIMIT(
"balance-limit");
78 static const std::string KEY_BALANCE_HIGHER_LIMIT_VALUE(
"higher-value");
79 static const std::string KEY_BALANCE_LOWER_LIMIT_VALUE(
"lower-value");
80 static const std::string KEY_BALANCE_INCLUDE_SUB_ACCTS(
"inlude-sub-accts");
82 using FinalProbabilityVec=std::vector<std::pair<std::string, int32_t>>;
83 using ProbabilityVec=std::vector<std::pair<std::string, struct AccountProbability>>;
84 using FlatKvpEntry=std::pair<std::string, KvpValue*>;
107 PROP_END_NOCLOSING_BALANCE,
108 PROP_END_CLEARED_BALANCE,
109 PROP_END_RECONCILED_BALANCE,
114 PROP_TAX_COPY_NUMBER,
125 PROP_IMP_APPEND_TEXT,
126 PROP_IS_OPENING_BALANCE,
127 PROP_OFX_INCOME_ACCOUNT,
131 PROP_AB_TRANS_RETRIEVAL,
139 PROP_START_NOCLOSING_BALANCE,
140 PROP_START_CLEARED_BALANCE,
141 PROP_START_RECONCILED_BALANCE,
144 #define GET_PRIVATE(o) \ 145 ((AccountPrivate*)gnc_account_get_instance_private((Account*)o)) 148 static const std::map<GNCAccountType, const char*> gnc_acct_debit_strs = {
165 static const char* dflt_acct_debit_str = N_(
"Debit");
168 static const std::map<GNCAccountType, const char*> gnc_acct_credit_strs = {
185 static const char* dflt_acct_credit_str = N_(
"Credit");
194 static void xaccAccountBringUpToDate (
Account *acc);
207 return account_separator;
211 gnc_get_account_separator (
void)
213 return account_uc_separator;
217 gnc_set_account_separator (
const gchar *separator)
222 uc = g_utf8_get_char_validated(separator, -1);
223 if ((uc == (gunichar) - 2) || (uc == (gunichar) - 1) || g_unichar_isalnum(uc))
225 account_uc_separator =
':';
226 strcpy(account_separator,
":");
230 account_uc_separator = uc;
231 count = g_unichar_to_utf8(uc, account_separator);
232 account_separator[count] =
'\0';
237 gchar *message =
nullptr;
239 if ( !invalid_account_names )
248 message = g_strdup_printf(
249 _(
"The separator character \"%s\" is used in one or more account names.\n\n" 250 "This will result in unexpected behaviour. " 251 "Either change the account names or choose another separator character.\n\n" 252 "Below you will find the list of invalid account names:\n" 253 "%s"), separator, account_list );
254 g_free ( account_list );
261 const gchar *separator;
265 check_acct_name (
Account *acct, gpointer user_data)
269 if (g_strstr_len (name, -1, cb->separator))
270 cb->list = g_list_prepend (cb->list, g_strdup (name));
275 g_return_val_if_fail (separator !=
nullptr,
nullptr);
276 if (!book)
return nullptr;
279 (AccountCb)check_acct_name, &cb);
286 static inline void mark_account (
Account *acc);
290 qof_instance_set_dirty(&acc->inst);
297 G_DEFINE_TYPE_WITH_PRIVATE(
Account, gnc_account, QOF_TYPE_INSTANCE)
304 priv = GET_PRIVATE(acc);
305 priv->parent =
nullptr;
316 priv->lots =
nullptr;
318 priv->commodity =
nullptr;
319 priv->commodity_scu = 0;
320 priv->non_standard_scu = FALSE;
322 priv->balance = gnc_numeric_zero();
323 priv->noclosing_balance = gnc_numeric_zero();
324 priv->cleared_balance = gnc_numeric_zero();
325 priv->reconciled_balance = gnc_numeric_zero();
326 priv->starting_balance = gnc_numeric_zero();
327 priv->starting_noclosing_balance = gnc_numeric_zero();
328 priv->starting_cleared_balance = gnc_numeric_zero();
329 priv->starting_reconciled_balance = gnc_numeric_zero();
330 priv->balance_dirty = FALSE;
332 new (&priv->children) AccountVec ();
333 new (&priv->splits) SplitsVec ();
334 priv->splits_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
335 priv->sort_dirty = FALSE;
339 gnc_account_dispose (GObject *acctp)
341 G_OBJECT_CLASS(gnc_account_parent_class)->dispose(acctp);
345 gnc_account_finalize(GObject* acctp)
347 G_OBJECT_CLASS(gnc_account_parent_class)->finalize(acctp);
357 gnc_account_get_property (GObject *
object,
365 g_return_if_fail(GNC_IS_ACCOUNT(
object));
367 account = GNC_ACCOUNT(
object);
368 priv = GET_PRIVATE(account);
372 g_value_set_string(value, priv->accountName);
378 g_value_set_string(value, priv->accountCode);
380 case PROP_DESCRIPTION:
381 g_value_set_string(value, priv->description);
391 g_value_set_int(value, priv->type);
394 g_value_take_object(value, priv->commodity);
396 case PROP_COMMODITY_SCU:
397 g_value_set_int(value, priv->commodity_scu);
399 case PROP_NON_STD_SCU:
400 g_value_set_boolean(value, priv->non_standard_scu);
402 case PROP_SORT_DIRTY:
403 g_value_set_boolean(value, priv->sort_dirty);
405 case PROP_BALANCE_DIRTY:
406 g_value_set_boolean(value, priv->balance_dirty);
408 case PROP_START_BALANCE:
409 g_value_set_boxed(value, &priv->starting_balance);
411 case PROP_START_NOCLOSING_BALANCE:
412 g_value_set_boxed(value, &priv->starting_noclosing_balance);
414 case PROP_START_CLEARED_BALANCE:
415 g_value_set_boxed(value, &priv->starting_cleared_balance);
417 case PROP_START_RECONCILED_BALANCE:
418 g_value_set_boxed(value, &priv->starting_reconciled_balance);
420 case PROP_END_BALANCE:
421 g_value_set_boxed(value, &priv->balance);
423 case PROP_END_NOCLOSING_BALANCE:
424 g_value_set_boxed(value, &priv->noclosing_balance);
426 case PROP_END_CLEARED_BALANCE:
427 g_value_set_boxed(value, &priv->cleared_balance);
429 case PROP_END_RECONCILED_BALANCE:
430 g_value_set_boxed(value, &priv->reconciled_balance);
434 g_value_set_pointer(value, priv->policy);
437 g_value_set_int(value, priv->mark);
439 case PROP_TAX_RELATED:
445 case PROP_TAX_SOURCE:
446 g_value_set_string(value,
449 case PROP_TAX_COPY_NUMBER:
450 g_value_set_int64(value,
456 case PROP_AUTO_INTEREST:
459 case PROP_IS_OPENING_BALANCE:
462 case PROP_PLACEHOLDER:
468 case PROP_SORT_ORDER:
471 case PROP_SORT_REVERSED:
474 case PROP_LOT_NEXT_ID:
476 g_value_set_int64 (value, 0);
477 qof_instance_get_path_kvp (QOF_INSTANCE (account), value, {KEY_LOT_MGMT,
"next-id"});
479 case PROP_ONLINE_ACCOUNT:
480 qof_instance_get_path_kvp (QOF_INSTANCE (account), value, {KEY_ONLINE_ID});
482 case PROP_IMP_APPEND_TEXT:
485 case PROP_OFX_INCOME_ACCOUNT:
486 qof_instance_get_path_kvp (QOF_INSTANCE (account), value, {KEY_ASSOC_INCOME_ACCOUNT});
488 case PROP_AB_ACCOUNT_ID:
489 qof_instance_get_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_ACCOUNT_ID});
491 case PROP_AB_ACCOUNT_UID:
492 qof_instance_get_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_ACCOUNT_UID});
494 case PROP_AB_BANK_CODE:
495 qof_instance_get_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_BANK_CODE});
497 case PROP_AB_TRANS_RETRIEVAL:
498 qof_instance_get_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_TRANS_RETRIEVAL});
501 G_OBJECT_WARN_INVALID_PROPERTY_ID(
object, prop_id, pspec);
507 gnc_account_set_property (GObject *
object,
514 g_return_if_fail(GNC_IS_ACCOUNT(
object));
515 account = GNC_ACCOUNT(
object);
516 if (prop_id < PROP_RUNTIME_0)
517 g_assert (qof_instance_get_editlevel(account));
527 case PROP_DESCRIPTION:
543 case PROP_COMMODITY_SCU:
546 case PROP_NON_STD_SCU:
549 case PROP_SORT_DIRTY:
552 case PROP_BALANCE_DIRTY:
555 case PROP_START_BALANCE:
556 number =
static_cast<gnc_numeric*
>(g_value_get_boxed(value));
559 case PROP_START_CLEARED_BALANCE:
560 number =
static_cast<gnc_numeric*
>(g_value_get_boxed(value));
563 case PROP_START_RECONCILED_BALANCE:
564 number =
static_cast<gnc_numeric*
>(g_value_get_boxed(value));
573 case PROP_TAX_RELATED:
579 case PROP_TAX_SOURCE:
581 g_value_get_string(value));
583 case PROP_TAX_COPY_NUMBER:
585 g_value_get_int64(value));
590 case PROP_AUTO_INTEREST:
593 case PROP_IS_OPENING_BALANCE:
596 case PROP_PLACEHOLDER:
602 case PROP_SORT_ORDER:
605 case PROP_SORT_REVERSED:
608 case PROP_LOT_NEXT_ID:
609 qof_instance_set_path_kvp (QOF_INSTANCE (account), value, {KEY_LOT_MGMT,
"next-id"});
611 case PROP_ONLINE_ACCOUNT:
612 qof_instance_set_path_kvp (QOF_INSTANCE (account), value, {KEY_ONLINE_ID});
614 case PROP_IMP_APPEND_TEXT:
617 case PROP_OFX_INCOME_ACCOUNT:
618 qof_instance_set_path_kvp (QOF_INSTANCE (account), value, {KEY_ASSOC_INCOME_ACCOUNT});
620 case PROP_AB_ACCOUNT_ID:
621 qof_instance_set_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_ACCOUNT_ID});
623 case PROP_AB_ACCOUNT_UID:
624 qof_instance_set_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_ACCOUNT_UID});
626 case PROP_AB_BANK_CODE:
627 qof_instance_set_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_BANK_CODE});
629 case PROP_AB_TRANS_RETRIEVAL:
630 qof_instance_set_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_TRANS_RETRIEVAL});
633 G_OBJECT_WARN_INVALID_PROPERTY_ID(
object, prop_id, pspec);
641 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
643 gobject_class->dispose = gnc_account_dispose;
644 gobject_class->finalize = gnc_account_finalize;
645 gobject_class->set_property = gnc_account_set_property;
646 gobject_class->get_property = gnc_account_get_property;
648 g_object_class_install_property
651 g_param_spec_string (
"name",
653 "The accountName is an arbitrary string " 654 "assigned by the user. It is intended to " 655 "a short, 5 to 30 character long string " 656 "that is displayed by the GUI as the " 657 "account mnemonic. Account names may be " 658 "repeated. but no two accounts that share " 659 "a parent may have the same name.",
661 static_cast<GParamFlags>(G_PARAM_READWRITE)));
663 g_object_class_install_property
666 g_param_spec_string (
"fullname",
668 "The name of the account concatenated with " 669 "all its parent account names to indicate " 672 static_cast<GParamFlags>(G_PARAM_READABLE)));
674 g_object_class_install_property
677 g_param_spec_string (
"code",
679 "The account code is an arbitrary string " 680 "assigned by the user. It is intended to " 681 "be reporting code that is a synonym for " 684 static_cast<GParamFlags>(G_PARAM_READWRITE)));
686 g_object_class_install_property
689 g_param_spec_string (
"description",
690 "Account Description",
691 "The account description is an arbitrary " 692 "string assigned by the user. It is intended " 693 "to be a longer, 1-5 sentence description of " 694 "what this account is all about.",
696 static_cast<GParamFlags>(G_PARAM_READWRITE)));
698 g_object_class_install_property
701 g_param_spec_string (
"color",
703 "The account color is a color string assigned " 704 "by the user. It is intended to highlight the " 705 "account based on the users wishes.",
707 static_cast<GParamFlags>(G_PARAM_READWRITE)));
709 g_object_class_install_property
712 g_param_spec_string (
"notes",
714 "The account notes is an arbitrary provided " 715 "for the user to attach any other text that " 716 "they would like to associate with the account.",
718 static_cast<GParamFlags>(G_PARAM_READWRITE)));
720 g_object_class_install_property
723 g_param_spec_int (
"type",
725 "The account type, picked from the enumerated list " 726 "that includes ACCT_TYPE_BANK, ACCT_TYPE_STOCK, " 727 "ACCT_TYPE_CREDIT, ACCT_TYPE_INCOME, etc.",
731 static_cast<GParamFlags>(G_PARAM_READWRITE)));
733 g_object_class_install_property
736 g_param_spec_object (
"commodity",
738 "The commodity field denotes the kind of " 739 "'stuff' stored in this account, whether " 740 "it is USD, gold, stock, etc.",
742 static_cast<GParamFlags>(G_PARAM_READWRITE)));
744 g_object_class_install_property
747 g_param_spec_int (
"commodity-scu",
749 "The smallest fraction of the commodity that is " 750 "tracked. This number is used as the denominator " 751 "value in 1/x, so a value of 100 says that the " 752 "commodity can be divided into hundredths. E.G." 753 "1 USD can be divided into 100 cents.",
757 static_cast<GParamFlags>(G_PARAM_READWRITE)));
759 g_object_class_install_property
762 g_param_spec_boolean (
"non-std-scu",
764 "TRUE if the account SCU doesn't match " 765 "the commodity SCU. This indicates a case " 766 "where the two were accidentally set to " 767 "mismatched values in older versions of " 770 static_cast<GParamFlags>(G_PARAM_READWRITE)));
772 g_object_class_install_property
775 g_param_spec_boolean(
"sort-dirty",
777 "TRUE if the splits in the account needs to be " 778 "resorted. This flag is set by the accounts " 779 "code for certain internal modifications, or " 780 "when external code calls the engine to say a " 781 "split has been modified in a way that may " 782 "affect the sort order of the account. Note: " 783 "This value can only be set to TRUE.",
785 static_cast<GParamFlags>(G_PARAM_READWRITE)));
787 g_object_class_install_property
790 g_param_spec_boolean(
"balance-dirty",
792 "TRUE if the running balances in the account " 793 "needs to be recalculated. This flag is set " 794 "by the accounts code for certain internal " 795 "modifications, or when external code calls " 796 "the engine to say a split has been modified. " 797 "Note: This value can only be set to TRUE.",
799 static_cast<GParamFlags>(G_PARAM_READWRITE)));
801 g_object_class_install_property
804 g_param_spec_boxed(
"start-balance",
806 "The starting balance for the account. This " 807 "parameter is intended for use with backends that " 808 "do not return the complete list of splits for an " 809 "account, but rather return a partial list. In " 810 "such a case, the backend will typically return " 811 "all of the splits after some certain date, and " 812 "the 'starting balance' will represent the " 813 "summation of the splits up to that date.",
815 static_cast<GParamFlags>(G_PARAM_READWRITE)));
817 g_object_class_install_property
819 PROP_START_NOCLOSING_BALANCE,
820 g_param_spec_boxed(
"start-noclosing-balance",
821 "Starting No-closing Balance",
822 "The starting balance for the account, ignoring closing." 823 "This parameter is intended for use with backends " 824 "that do not return the complete list of splits " 825 "for an account, but rather return a partial " 826 "list. In such a case, the backend will " 827 "typically return all of the splits after " 828 "some certain date, and the 'starting noclosing " 829 "balance' will represent the summation of the " 830 "splits up to that date, ignoring closing splits.",
832 static_cast<GParamFlags>(G_PARAM_READWRITE)));
834 g_object_class_install_property
836 PROP_START_CLEARED_BALANCE,
837 g_param_spec_boxed(
"start-cleared-balance",
838 "Starting Cleared Balance",
839 "The starting cleared balance for the account. " 840 "This parameter is intended for use with backends " 841 "that do not return the complete list of splits " 842 "for an account, but rather return a partial " 843 "list. In such a case, the backend will " 844 "typically return all of the splits after " 845 "some certain date, and the 'starting cleared " 846 "balance' will represent the summation of the " 847 "splits up to that date.",
849 static_cast<GParamFlags>(G_PARAM_READWRITE)));
851 g_object_class_install_property
853 PROP_START_RECONCILED_BALANCE,
854 g_param_spec_boxed(
"start-reconciled-balance",
855 "Starting Reconciled Balance",
856 "The starting reconciled balance for the " 857 "account. This parameter is intended for use " 858 "with backends that do not return the complete " 859 "list of splits for an account, but rather return " 860 "a partial list. In such a case, the backend " 861 "will typically return all of the splits after " 862 "some certain date, and the 'starting reconciled " 863 "balance' will represent the summation of the " 864 "splits up to that date.",
866 static_cast<GParamFlags>(G_PARAM_READWRITE)));
868 g_object_class_install_property
871 g_param_spec_boxed(
"end-balance",
872 "Ending Account Balance",
873 "This is the current ending balance for the " 874 "account. It is computed from the sum of the " 875 "starting balance and all splits in the account.",
879 g_object_class_install_property
881 PROP_END_NOCLOSING_BALANCE,
882 g_param_spec_boxed(
"end-noclosing-balance",
883 "Ending Account Noclosing Balance",
884 "This is the current ending no-closing balance for " 885 "the account. It is computed from the sum of the " 886 "starting balance and all cleared splits in the " 891 g_object_class_install_property
893 PROP_END_CLEARED_BALANCE,
894 g_param_spec_boxed(
"end-cleared-balance",
895 "Ending Account Cleared Balance",
896 "This is the current ending cleared balance for " 897 "the account. It is computed from the sum of the " 898 "starting balance and all cleared splits in the " 903 g_object_class_install_property
905 PROP_END_RECONCILED_BALANCE,
906 g_param_spec_boxed(
"end-reconciled-balance",
907 "Ending Account Reconciled Balance",
908 "This is the current ending reconciled balance " 909 "for the account. It is computed from the sum of " 910 "the starting balance and all reconciled splits " 913 static_cast<GParamFlags>(G_PARAM_READABLE)));
915 g_object_class_install_property
918 g_param_spec_pointer (
"policy",
920 "The account lots policy.",
921 static_cast<GParamFlags>(G_PARAM_READWRITE)));
923 g_object_class_install_property
926 g_param_spec_int (
"acct-mark",
932 static_cast<GParamFlags>(G_PARAM_READWRITE)));
934 g_object_class_install_property
937 g_param_spec_boolean (
"tax-related",
939 "Whether the account maps to an entry on an " 940 "income tax document.",
942 static_cast<GParamFlags>(G_PARAM_READWRITE)));
944 g_object_class_install_property
946 PROP_IS_OPENING_BALANCE,
947 g_param_spec_boolean (
"opening-balance",
949 "Whether the account holds opening balances",
951 static_cast<GParamFlags>(G_PARAM_READWRITE)));
953 g_object_class_install_property
956 g_param_spec_string (
"tax-code",
958 "This is the code for mapping an account to a " 959 "specific entry on a taxable document. In the " 960 "United States it is used to transfer totals " 961 "into tax preparation software.",
963 static_cast<GParamFlags>(G_PARAM_READWRITE)));
965 g_object_class_install_property
968 g_param_spec_string (
"tax-source",
970 "This specifies where exported name comes from.",
972 static_cast<GParamFlags>(G_PARAM_READWRITE)));
974 g_object_class_install_property
976 PROP_TAX_COPY_NUMBER,
977 g_param_spec_int64 (
"tax-copy-number",
979 "This specifies the copy number of the tax " 984 static_cast<GParamFlags>(G_PARAM_READWRITE)));
986 g_object_class_install_property
989 g_param_spec_boolean (
"hidden",
991 "Whether the account should be hidden in the " 994 static_cast<GParamFlags>(G_PARAM_READWRITE)));
996 g_object_class_install_property
999 g_param_spec_boolean (
"auto-interest-transfer",
1001 "Whether an interest transfer should be automatically " 1002 "added before reconcile.",
1004 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1006 g_object_class_install_property
1009 g_param_spec_boolean (
"placeholder",
1011 "Whether the account is a placeholder account which does not " 1012 "allow transactions to be created, edited or deleted.",
1014 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1016 g_object_class_install_property
1019 g_param_spec_string (
"filter",
1021 "The account filter is a value saved to allow " 1022 "filters to be recalled.",
1024 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1026 g_object_class_install_property
1029 g_param_spec_string (
"sort-order",
1030 "Account Sort Order",
1031 "The account sort order is a value saved to allow " 1032 "the sort order to be recalled.",
1034 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1036 g_object_class_install_property
1039 g_param_spec_boolean (
"sort-reversed",
1040 "Account Sort Reversed",
1041 "Parameter to store whether the sort order is reversed or not.",
1043 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1045 g_object_class_install_property
1048 g_param_spec_int64 (
"lot-next-id",
1050 "Tracks the next id to use in gnc_lot_make_default.",
1054 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1056 g_object_class_install_property
1058 PROP_ONLINE_ACCOUNT,
1059 g_param_spec_string (
"online-id",
1060 "Online Account ID",
1061 "The online account which corresponds to this " 1062 "account for OFX import",
1064 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1066 g_object_class_install_property
1068 PROP_IMP_APPEND_TEXT,
1069 g_param_spec_boolean (
"import-append-text",
1070 "Import Append Text",
1071 "Saved state of Append checkbox for setting initial " 1072 "value next time this account is imported.",
1074 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1076 g_object_class_install_property(
1078 PROP_OFX_INCOME_ACCOUNT,
1079 g_param_spec_boxed(
"ofx-income-account",
1080 "Associated income account",
1081 "Used by the OFX importer.",
1083 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1085 g_object_class_install_property
1088 g_param_spec_string (
"ab-account-id",
1089 "AQBanking Account ID",
1090 "The AqBanking account which corresponds to this " 1091 "account for AQBanking import",
1093 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1094 g_object_class_install_property
1097 g_param_spec_string (
"ab-bank-code",
1098 "AQBanking Bank Code",
1099 "The online account which corresponds to this " 1100 "account for AQBanking import",
1102 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1104 g_object_class_install_property
1106 PROP_AB_ACCOUNT_UID,
1107 g_param_spec_int64 (
"ab-account-uid",
1108 "AQBanking Account UID",
1109 "Tracks the next id to use in gnc_lot_make_default.",
1113 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1115 g_object_class_install_property
1117 PROP_AB_TRANS_RETRIEVAL,
1118 g_param_spec_boxed(
"ab-trans-retrieval",
1119 "AQBanking Last Transaction Retrieval",
1120 "The time of the last transaction retrieval for this " 1123 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1128 xaccInitAccount (
Account * acc, QofBook *book)
1130 ENTER (
"book=%p\n", book);
1133 LEAVE (
"account=%p\n", acc);
1140 gnc_account_foreach_split (
const Account *acc, std::function<
void(Split*)> func)
1142 if (!GNC_IS_ACCOUNT (acc))
1145 auto& splits{GET_PRIVATE(acc)->splits};
1146 std::for_each (splits.begin(), splits.end(), func);
1150 gnc_account_foreach_split_until_date (
const Account *acc,
time64 end_date,
1151 std::function<
void(Split*)> f)
1153 if (!GNC_IS_ACCOUNT (acc))
1156 auto after_date = [](
time64 end_date,
auto s) ->
bool 1159 auto& splits{GET_PRIVATE(acc)->splits};
1160 auto after_date_iter = std::upper_bound (splits.begin(), splits.end(), end_date, after_date);
1161 std::for_each (splits.begin(), after_date_iter, f);
1169 if (!GNC_IS_ACCOUNT (acc))
1172 const auto& splits{GET_PRIVATE(acc)->splits};
1175 auto latest = std::find_if(splits.rbegin(), splits.rend(), predicate);
1176 return (latest == splits.rend()) ?
nullptr : *latest;
1180 auto earliest = std::find_if(splits.begin(), splits.end(), predicate);
1181 return (earliest == splits.end()) ?
nullptr : *earliest;
1189 gnc_account_get_book(
const Account *account)
1191 if (!account)
return nullptr;
1199 gnc_coll_get_root_account (QofCollection *col)
1201 if (!col)
return nullptr;
1206 gnc_coll_set_root_account (QofCollection *col,
Account *root)
1212 old_root = gnc_coll_get_root_account (col);
1213 if (old_root == root)
return;
1218 rpriv = GET_PRIVATE(root);
1226 qof_collection_set_data (col, root);
1236 gnc_book_get_root_account (QofBook *book)
1241 if (!book)
return nullptr;
1243 root = gnc_coll_get_root_account (col);
1250 gnc_book_set_root_account (QofBook *book,
Account *root)
1255 if (root && gnc_account_get_book(root) != book)
1257 PERR (
"cannot mix and match books freely!");
1262 gnc_coll_set_root_account (col, root);
1273 g_return_val_if_fail (book,
nullptr);
1275 acc =
static_cast<Account*
>(g_object_new (GNC_TYPE_ACCOUNT,
nullptr));
1276 xaccInitAccount (acc, book);
1289 rpriv = GET_PRIVATE(root);
1293 mark_account (root);
1295 gnc_book_set_root_account(book, root);
1305 g_return_val_if_fail(GNC_IS_ACCOUNT(from),
nullptr);
1306 g_return_val_if_fail(QOF_IS_BOOK(book),
nullptr);
1309 ret =
static_cast<Account*
>(g_object_new (GNC_TYPE_ACCOUNT,
nullptr));
1310 g_return_val_if_fail (ret,
nullptr);
1312 from_priv = GET_PRIVATE(from);
1313 priv = GET_PRIVATE(ret);
1314 xaccInitAccount (ret, book);
1319 priv->type = from_priv->type;
1325 qof_instance_copy_kvp (QOF_INSTANCE (ret), QOF_INSTANCE (from));
1332 priv->commodity_scu = from_priv->commodity_scu;
1333 priv->non_standard_scu = from_priv->non_standard_scu;
1335 qof_instance_set_dirty(&ret->inst);
1344 xaccFreeOneChildAccount (
Account *acc)
1348 if (qof_instance_get_editlevel(acc) == 0)
1354 xaccFreeAccountChildren (
Account *acc)
1356 auto priv{GET_PRIVATE(acc)};
1358 auto children = priv->children;
1359 std::for_each (children.begin(), children.end(), xaccFreeOneChildAccount);
1362 priv->children.clear();
1370 xaccFreeAccount (
Account *acc)
1375 g_return_if_fail(GNC_IS_ACCOUNT(acc));
1377 priv = GET_PRIVATE(acc);
1384 qof_instance_set_destroying(acc, TRUE);
1386 if (!priv->children.empty())
1388 PERR (
" instead of calling xaccFreeAccount(), please call\n" 1389 " xaccAccountBeginEdit(); xaccAccountDestroy();\n");
1392 xaccFreeAccountChildren(acc);
1398 PERR (
" instead of calling xaccFreeAccount(), please call\n" 1399 " xaccAccountBeginEdit(); xaccAccountDestroy();\n");
1401 for (lp = priv->lots; lp; lp = lp->next)
1403 GNCLot *lot =
static_cast<GNCLot*
>(lp->data);
1404 gnc_lot_destroy (lot);
1406 g_list_free (priv->lots);
1407 priv->lots =
nullptr;
1414 if (!priv->splits.empty())
1416 PERR (
" instead of calling xaccFreeAccount(), please call\n" 1417 " xaccAccountBeginEdit(); xaccAccountDestroy();\n");
1419 qof_instance_reset_editlevel(acc);
1421 for (
auto s : priv->splits)
1434 priv->accountName = priv->accountCode = priv->description =
nullptr;
1439 priv->last_num =
nullptr;
1440 priv->tax_us_code =
nullptr;
1441 priv->tax_us_pns =
nullptr;
1442 priv->color =
nullptr;
1443 priv->sort_order =
nullptr;
1444 priv->notes =
nullptr;
1445 priv->filter =
nullptr;
1447 priv->parent =
nullptr;
1449 priv->balance = gnc_numeric_zero();
1450 priv->noclosing_balance = gnc_numeric_zero();
1451 priv->cleared_balance = gnc_numeric_zero();
1452 priv->reconciled_balance = gnc_numeric_zero();
1456 priv->commodity =
nullptr;
1458 priv->balance_dirty = FALSE;
1459 priv->sort_dirty = FALSE;
1460 priv->splits.~SplitsVec();
1461 priv->children.~AccountVec();
1462 g_hash_table_destroy (priv->splits_hash);
1465 g_object_unref(acc);
1475 g_return_if_fail(acc);
1487 PERR(
"commit error: %d", errcode);
1488 gnc_engine_signal_commit_error( errcode );
1496 priv = GET_PRIVATE(acc);
1499 xaccFreeAccount(acc);
1503 destroy_pending_splits_for_account(
QofInstance *ent, gpointer acc)
1505 Transaction *trans = (Transaction *) ent;
1509 while ((split = xaccTransFindSplitByAccount(trans, static_cast<Account*>(acc))))
1519 g_return_if_fail(acc);
1524 priv = GET_PRIVATE(acc);
1529 qof_instance_increase_editlevel(acc);
1532 xaccFreeAccountChildren(acc);
1534 PINFO (
"freeing splits for account %p (%s)",
1535 acc, priv->accountName ? priv->accountName :
"(null)");
1544 for_each(priv->splits.rbegin(), priv->splits.rend(), [](Split *s) {
1549 priv->splits.clear();
1550 g_hash_table_remove_all (priv->splits_hash);
1564 qof_collection_foreach(col, destroy_pending_splits_for_account, acc);
1567 for (
auto lp = priv->lots; lp; lp = lp->next)
1569 GNCLot *lot =
static_cast<GNCLot*
>(lp->data);
1570 gnc_lot_destroy (lot);
1573 g_list_free(priv->lots);
1574 priv->lots =
nullptr;
1576 qof_instance_set_dirty(&acc->inst);
1577 qof_instance_decrease_editlevel(acc);
1581 xaccAccountBringUpToDate(acc);
1590 g_return_if_fail(GNC_IS_ACCOUNT(acc));
1592 qof_instance_set_destroying(acc, TRUE);
1600 auto priv = GET_PRIVATE(acc);
1601 std::vector<Transaction*> transactions;
1602 transactions.reserve(priv->splits.size());
1603 std::transform(priv->splits.begin(), priv->splits.end(),
1604 back_inserter(transactions),
1605 [](
auto split) {
return split->parent; });
1606 std::stable_sort(transactions.begin(), transactions.end());
1607 transactions.erase(std::unique(transactions.begin(), transactions.end()),
1608 transactions.end());
1610 std::for_each(transactions.rbegin(), transactions.rend(),
1619 xaccAcctChildrenEqual(
const AccountVec& na,
1620 const AccountVec& nb,
1621 gboolean check_guids)
1623 if (na.size() != nb.size())
1625 PINFO (
"Accounts have different numbers of children");
1631 auto it_b = std::find_if (nb.begin(), nb.end(), [aa](
auto ab) ->
bool 1633 if (!aa)
return (!ab);
1634 if (!ab)
return false;
1635 auto code_a{GET_PRIVATE(aa)->accountCode};
1636 auto code_b{GET_PRIVATE(ab)->accountCode};
1637 if ((code_a && *code_a) || (code_b && *code_b))
return !g_strcmp0 (code_a, code_b);
1638 return !g_strcmp0 (GET_PRIVATE(aa)->accountName, GET_PRIVATE(ab)->accountName);
1641 if (it_b == nb.end())
1643 PINFO (
"Unable to find matching child account.");
1654 PWARN (
"accounts %s and %s differ", sa, sb);
1668 if (!aa && !ab)
return TRUE;
1670 g_return_val_if_fail(GNC_IS_ACCOUNT(aa), FALSE);
1671 g_return_val_if_fail(GNC_IS_ACCOUNT(ab), FALSE);
1673 priv_aa = GET_PRIVATE(aa);
1674 priv_ab = GET_PRIVATE(ab);
1675 if (priv_aa->type != priv_ab->type)
1677 PWARN (
"types differ: %d vs %d", priv_aa->type, priv_ab->type);
1681 if (g_strcmp0(priv_aa->accountName, priv_ab->accountName) != 0)
1683 PWARN (
"names differ: %s vs %s", priv_aa->accountName, priv_ab->accountName);
1687 if (g_strcmp0(priv_aa->accountCode, priv_ab->accountCode) != 0)
1689 PWARN (
"codes differ: %s vs %s", priv_aa->accountCode, priv_ab->accountCode);
1693 if (g_strcmp0(priv_aa->description, priv_ab->description) != 0)
1695 PWARN (
"descriptions differ: %s vs %s", priv_aa->description, priv_ab->description);
1701 PWARN (
"commodities differ");
1709 PWARN (
"GUIDs differ");
1714 if (qof_instance_compare_kvp (QOF_INSTANCE (aa), QOF_INSTANCE (ab)) != 0)
1719 frame_a = qof_instance_kvp_as_string (QOF_INSTANCE (aa));
1720 frame_b = qof_instance_kvp_as_string (QOF_INSTANCE (ab));
1722 PWARN (
"kvp frames differ:\n%s\n\nvs\n\n%s", frame_a, frame_b);
1738 PWARN (
"starting balances differ: %s vs %s", str_a, str_b);
1747 priv_ab->starting_noclosing_balance))
1755 PWARN (
"starting noclosing balances differ: %s vs %s", str_a, str_b);
1763 priv_ab->starting_cleared_balance))
1771 PWARN (
"starting cleared balances differ: %s vs %s", str_a, str_b);
1780 priv_ab->starting_reconciled_balance))
1788 PWARN (
"starting reconciled balances differ: %s vs %s", str_a, str_b);
1804 PWARN (
"balances differ: %s vs %s", str_a, str_b);
1820 PWARN (
"noclosing balances differ: %s vs %s", str_a, str_b);
1835 PWARN (
"cleared balances differ: %s vs %s", str_a, str_b);
1843 if (!
gnc_numeric_equal(priv_aa->reconciled_balance, priv_ab->reconciled_balance))
1851 PWARN (
"reconciled balances differ: %s vs %s", str_a, str_b);
1861 if (!std::equal (priv_aa->splits.begin(), priv_aa->splits.end(),
1862 priv_ab->splits.begin(), priv_ab->splits.end(),
1863 [check_guids](
auto sa,
auto sb)
1866 PWARN (
"splits differ");
1870 if (!xaccAcctChildrenEqual(priv_aa->children, priv_ab->children, check_guids))
1872 PWARN (
"children differ");
1886 g_return_if_fail(GNC_IS_ACCOUNT(acc));
1891 priv = GET_PRIVATE(acc);
1892 priv->sort_dirty = TRUE;
1900 g_return_if_fail(GNC_IS_ACCOUNT(acc));
1905 priv = GET_PRIVATE(acc);
1906 priv->balance_dirty = TRUE;
1913 g_return_if_fail (GNC_IS_ACCOUNT (acc));
1918 priv = GET_PRIVATE (acc);
1919 priv->defer_bal_computation = defer;
1927 priv = GET_PRIVATE (acc);
1928 return priv->defer_bal_computation;
1935 static bool split_cmp_less (
const Split* a,
const Split* b)
1945 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
1946 g_return_val_if_fail(GNC_IS_SPLIT(s), FALSE);
1948 priv = GET_PRIVATE(acc);
1949 if (!g_hash_table_add (priv->splits_hash, s))
1952 priv->splits.push_back (s);
1954 if (qof_instance_get_editlevel(acc) == 0)
1955 std::sort (priv->splits.begin(), priv->splits.end(), split_cmp_less);
1957 priv->sort_dirty =
true;
1964 priv->balance_dirty = TRUE;
1975 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
1976 g_return_val_if_fail(GNC_IS_SPLIT(s), FALSE);
1978 priv = GET_PRIVATE(acc);
1980 if (!g_hash_table_remove (priv->splits_hash, s))
1985 if (s == priv->splits.back())
1986 priv->splits.pop_back();
1988 priv->splits.erase (std::remove (priv->splits.begin(), priv->splits.end(), s),
1989 priv->splits.end());
1996 priv->balance_dirty = TRUE;
2006 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2008 priv = GET_PRIVATE(acc);
2009 if (!priv->sort_dirty || (!force && qof_instance_get_editlevel(acc) > 0))
2011 std::sort (priv->splits.begin(), priv->splits.end(), split_cmp_less);
2012 priv->sort_dirty = FALSE;
2013 priv->balance_dirty = TRUE;
2017 xaccAccountBringUpToDate(
Account *acc)
2033 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2034 g_return_if_fail(guid);
2037 PINFO(
"acct=%p", acc);
2039 qof_instance_set_guid (&acc->inst, guid);
2040 qof_instance_set_dirty(&acc->inst);
2051 if (!guid || !book)
return nullptr;
2064 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2066 priv = GET_PRIVATE(acc);
2075 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2086 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2088 priv = GET_PRIVATE(acc);
2090 std::for_each (priv->children.begin(), priv->children.end(),
2100 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
2102 return GET_PRIVATE(acc)->policy;
2110 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2112 priv = GET_PRIVATE(acc);
2120 xaccAccountRemoveLot (
Account *acc, GNCLot *lot)
2124 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2125 g_return_if_fail(GNC_IS_LOT(lot));
2127 priv = GET_PRIVATE(acc);
2128 g_return_if_fail(priv->lots);
2130 ENTER (
"(acc=%p, lot=%p)", acc, lot);
2131 priv->lots = g_list_remove(priv->lots, lot);
2132 qof_event_gen (QOF_INSTANCE(lot), QOF_EVENT_REMOVE,
nullptr);
2134 LEAVE (
"(acc=%p, lot=%p)", acc, lot);
2145 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2146 g_return_if_fail(GNC_IS_LOT(lot));
2150 if (lot_account == acc)
2153 ENTER (
"(acc=%p, lot=%p)", acc, lot);
2158 old_acc = lot_account;
2159 opriv = GET_PRIVATE(old_acc);
2160 opriv->lots = g_list_remove(opriv->lots, lot);
2163 priv = GET_PRIVATE(acc);
2164 priv->lots = g_list_prepend(priv->lots, lot);
2165 gnc_lot_set_account(lot, acc);
2175 LEAVE (
"(acc=%p, lot=%p)", acc, lot);
2181 xaccPreSplitMove (Split *split)
2187 xaccPostSplitMove (Split *split,
Account *accto)
2191 xaccSplitSetAccount(split, accto);
2203 g_return_if_fail(GNC_IS_ACCOUNT(accfrom));
2204 g_return_if_fail(GNC_IS_ACCOUNT(accto));
2207 from_priv = GET_PRIVATE(accfrom);
2208 if (from_priv->splits.empty() || accfrom == accto)
2213 ENTER (
"(accfrom=%p, accto=%p)", accfrom, accto);
2218 std::for_each (from_priv->splits.begin(), from_priv->splits.end(), xaccPreSplitMove);
2235 auto splits = from_priv->splits;
2236 std::for_each (splits.begin(), splits.end(), [accto](
auto s){ xaccPostSplitMove (s, accto); });
2239 g_assert(from_priv->splits.empty());
2240 g_assert(from_priv->lots ==
nullptr);
2244 LEAVE (
"(accfrom=%p, accto=%p)", accfrom, accto);
2280 gnc_numeric balance;
2281 gnc_numeric noclosing_balance;
2282 gnc_numeric cleared_balance;
2283 gnc_numeric reconciled_balance;
2285 if (
nullptr == acc)
return;
2287 priv = GET_PRIVATE(acc);
2288 if (qof_instance_get_editlevel(acc) > 0)
return;
2289 if (!priv->balance_dirty || priv->defer_bal_computation)
return;
2293 balance = priv->starting_balance;
2294 noclosing_balance = priv->starting_noclosing_balance;
2295 cleared_balance = priv->starting_cleared_balance;
2296 reconciled_balance = priv->starting_reconciled_balance;
2298 PINFO (
"acct=%s starting baln=%" G_GINT64_FORMAT
"/%" G_GINT64_FORMAT,
2299 priv->accountName, balance.num, balance.denom);
2300 for (
auto split : priv->splits)
2304 balance = gnc_numeric_add_fixed(balance, amt);
2306 if (
NREC != split->reconciled)
2308 cleared_balance = gnc_numeric_add_fixed(cleared_balance, amt);
2311 if (
YREC == split->reconciled ||
2312 FREC == split->reconciled)
2314 reconciled_balance =
2315 gnc_numeric_add_fixed(reconciled_balance, amt);
2319 noclosing_balance = gnc_numeric_add_fixed(noclosing_balance, amt);
2321 split->balance = balance;
2322 split->noclosing_balance = noclosing_balance;
2323 split->cleared_balance = cleared_balance;
2324 split->reconciled_balance = reconciled_balance;
2328 priv->balance = balance;
2329 priv->noclosing_balance = noclosing_balance;
2330 priv->cleared_balance = cleared_balance;
2331 priv->reconciled_balance = reconciled_balance;
2332 priv->balance_dirty = FALSE;
2351 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
2359 const char *da, *db;
2362 if (aa == ab)
return 0;
2366 priv_aa = GET_PRIVATE(aa);
2367 priv_ab = GET_PRIVATE(ab);
2370 da = priv_aa->accountCode;
2371 db = priv_ab->accountCode;
2374 result = g_strcmp0 (da, db);
2380 if (-1 == revorder[0])
2385 revorder [typeorder[i]] = i;
2394 if (ta < tb)
return -1;
2395 if (ta > tb)
return +1;
2398 da = priv_aa->accountName;
2399 db = priv_ab->accountName;
2423 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2427 priv = GET_PRIVATE(acc);
2428 if (priv->type == tip)
2433 priv->balance_dirty = TRUE;
2444 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2445 g_return_if_fail(str);
2448 priv = GET_PRIVATE(acc);
2449 if (g_strcmp0(str, priv->accountName) == 0)
2464 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2467 priv = GET_PRIVATE(acc);
2468 if (g_strcmp0(str, priv->accountCode) == 0)
2483 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2486 priv = GET_PRIVATE(acc);
2487 if (g_strcmp0(str, priv->description) == 0)
2497 set_kvp_gnc_numeric_path (
Account *acc,
const std::vector<std::string>& path,
2498 std::optional<gnc_numeric> value)
2501 qof_instance_set_path_kvp<gnc_numeric> (QOF_INSTANCE(acc), value, path);
2505 static std::optional<gnc_numeric>
2506 get_kvp_gnc_numeric_path (
const Account *acc,
const Path& path)
2508 return qof_instance_get_path_kvp<gnc_numeric> (QOF_INSTANCE(acc), path);
2512 set_kvp_string_path (
Account *acc, std::vector<std::string>
const & path,
2515 std::optional<const char*> val;
2516 if (value && *value)
2517 val = g_strdup(value);
2520 qof_instance_set_path_kvp<const char*> (QOF_INSTANCE(acc), val, path);
2525 get_kvp_string_path (
const Account *acc,
const Path& path)
2527 auto rv{qof_instance_get_path_kvp<const char*> (QOF_INSTANCE(acc), path)};
2528 return rv ? *rv :
nullptr;
2532 set_kvp_account_path (
Account* acc,
const Path& path,
const Account* kvp_account)
2534 std::optional<GncGUID*> val;
2539 qof_instance_set_path_kvp<GncGUID*> (QOF_INSTANCE(acc), val, path);
2544 get_kvp_account_path (
const Account *acc,
const Path& path)
2546 auto val{qof_instance_get_path_kvp<GncGUID*> (QOF_INSTANCE(acc), path)};
2551 set_kvp_boolean_path (
Account *acc,
const Path& path, gboolean option)
2553 set_kvp_string_path (acc, path, option ?
"true" :
nullptr);
2557 get_kvp_boolean_path (
const Account *acc,
const Path& path)
2559 auto slot{QOF_INSTANCE(acc)->kvp_data->get_slot(path)};
2560 if (!slot)
return false;
2561 switch (slot->get_type())
2563 case KvpValueImpl::Type::INT64:
2564 return slot->get<int64_t>() != 0;
2565 case KvpValueImpl::Type::STRING:
2566 return g_strcmp0 (slot->get<
const char*>(),
"true") == 0;
2573 set_kvp_int64_path (
Account *acc,
const Path& path, std::optional<gint64> value)
2576 qof_instance_set_path_kvp<int64_t> (QOF_INSTANCE(acc), value, path);
2580 static const std::optional<gint64>
2581 get_kvp_int64_path (
const Account *acc,
const Path& path)
2583 return qof_instance_get_path_kvp<int64_t> (QOF_INSTANCE(acc), path);
2587 get_kvp_guid_path (
const Account *acc,
const Path& path)
2589 auto val{qof_instance_get_path_kvp<GncGUID*> (QOF_INSTANCE(acc), path)};
2596 set_kvp_string_path (acc, {
"color"}, str);
2602 set_kvp_string_path (acc, {
"filter"}, str);
2608 set_kvp_string_path (acc, {
"sort-order"}, str);
2614 set_kvp_boolean_path (acc, {
"sort-reversed"}, sortreversed);
2622 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2623 g_return_if_fail(GNC_IS_ACCOUNT(parent));
2625 parent_acc = GNC_ACCOUNT(parent);
2629 mark_account (parent_acc);
2638 set_kvp_string_path (acc, {
"notes"}, str);
2645 g_return_if_fail (GNC_IS_ACCOUNT(acc));
2646 g_return_if_fail (tag && *tag);
2648 set_kvp_account_path (acc, {
"associated-account", tag}, assoc_acct);
2657 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2658 g_return_if_fail(GNC_IS_COMMODITY(com));
2661 priv = GET_PRIVATE(acc);
2662 if (com == priv->commodity)
2667 priv->commodity = com;
2670 priv->non_standard_scu = FALSE;
2673 for (
auto s : priv->splits)
2682 priv->sort_dirty = TRUE;
2683 priv->balance_dirty = TRUE;
2700 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2702 priv = GET_PRIVATE(acc);
2704 priv->commodity_scu = scu;
2706 priv->non_standard_scu = TRUE;
2714 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0);
2715 return GET_PRIVATE(acc)->commodity_scu;
2723 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0);
2725 priv = GET_PRIVATE(acc);
2726 if (priv->non_standard_scu || !priv->commodity)
2727 return priv->commodity_scu;
2736 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2738 priv = GET_PRIVATE(acc);
2739 if (priv->non_standard_scu == flag)
2742 priv->non_standard_scu = flag;
2750 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0);
2751 return GET_PRIVATE(acc)->non_standard_scu;
2761 if ((!acc) || (!currency))
return;
2764 set_kvp_string_path (acc, {
"old-currency"}, s);
2768 auto commodity = gnc_commodity_table_lookup_unique (
table, s);
2780 g_return_if_fail (GNC_IS_ACCOUNT(acc));
2785 auto children = GET_PRIVATE(acc)->children;
2786 for (
auto child : children)
2794 account_foreach_descendant_sorted (
const Account *acc, std::function<
void(
Account*)> account_cb)
2796 g_return_if_fail (GNC_IS_ACCOUNT(acc));
2798 auto children = GET_PRIVATE(acc)->children;
2799 std::sort (children.begin(), children.end(),
2802 for (
auto child : children)
2805 account_foreach_descendant_sorted (child, account_cb);
2817 g_assert(GNC_IS_ACCOUNT(new_parent));
2818 g_assert(GNC_IS_ACCOUNT(child));
2821 ppriv = GET_PRIVATE(new_parent);
2822 cpriv = GET_PRIVATE(child);
2823 old_parent = cpriv->parent;
2824 if (old_parent == new_parent)
2846 PWARN (
"reparenting accounts across books is not correctly supported\n");
2855 cpriv->parent = new_parent;
2856 ppriv->children.push_back (child);
2857 qof_instance_set_dirty(&new_parent->inst);
2858 qof_instance_set_dirty(&child->inst);
2881 if (!parent)
return;
2883 ppriv = GET_PRIVATE(parent);
2884 cpriv = GET_PRIVATE(child);
2886 if (cpriv->parent != parent)
2888 PERR (
"account not a child of parent");
2896 ppriv->children.erase (std::remove (ppriv->children.begin(), ppriv->children.end(), child),
2897 ppriv->children.end());
2903 cpriv->parent =
nullptr;
2911 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
2912 return GET_PRIVATE(acc)->parent;
2918 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
2929 g_return_val_if_fail(GNC_IS_ACCOUNT(account), FALSE);
2930 return (GET_PRIVATE(account)->parent ==
nullptr);
2936 g_return_val_if_fail(GNC_IS_ACCOUNT(account),
nullptr);
2937 auto& children = GET_PRIVATE(account)->children;
2938 return std::accumulate (children.rbegin(), children.rend(),
static_cast<GList*
>(
nullptr),
2945 g_return_val_if_fail(GNC_IS_ACCOUNT(account),
nullptr);
2952 g_return_val_if_fail(GNC_IS_ACCOUNT(account), 0);
2953 return GET_PRIVATE(account)->children.size();
2959 g_return_val_if_fail(GNC_IS_ACCOUNT(parent), -1);
2960 g_return_val_if_fail(GNC_IS_ACCOUNT(child), -1);
2961 auto& children = GET_PRIVATE(parent)->children;
2962 auto find_it = std::find (children.begin(), children.end(), child);
2963 return find_it == children.end() ? -1 : std::distance (children.begin(), find_it);
2969 g_return_val_if_fail(GNC_IS_ACCOUNT(parent),
nullptr);
2970 if ((
size_t)num >= GET_PRIVATE(parent)->children.size())
2972 return static_cast<Account*
>(GET_PRIVATE(parent)->children.at (num));
2989 g_return_val_if_fail(GNC_IS_ACCOUNT(account), 0);
2991 priv = GET_PRIVATE(account);
2994 account = priv->parent;
2995 priv = GET_PRIVATE(account);
3006 g_return_val_if_fail(GNC_IS_ACCOUNT(account), 0);
3008 priv = GET_PRIVATE(account);
3009 if (!priv->children.size())
3012 return 1 + std::accumulate (priv->children.begin(), priv->children.end(),
3013 0, [](
auto a,
auto b)
3020 GList* list =
nullptr;
3022 return g_list_reverse (list);
3028 GList* list =
nullptr;
3029 account_foreach_descendant_sorted (account, [&list](
auto a){ list = g_list_prepend (list, a); });
3030 return g_list_reverse (list);
3039 account_foreach_descendant_breadthfirst_until (
const Account *acc,
3043 g_return_val_if_fail (GNC_IS_ACCOUNT(acc),
nullptr);
3044 g_return_val_if_fail (thunk,
nullptr);
3046 auto& children{GET_PRIVATE(acc)->children};
3048 for (
auto acc : children)
3049 if (
auto result = thunk (acc, user_data))
3052 for (
auto acc: children)
3053 if (
auto result = account_foreach_descendant_breadthfirst_until (acc, thunk, user_data))
3060 is_acct_name (
Account *account, gpointer user_data)
3062 auto name {
static_cast<gchar*
>(user_data)};
3069 return (
Account*)account_foreach_descendant_breadthfirst_until (parent, is_acct_name, (
char*)name);
3073 is_acct_code (
Account *account, gpointer user_data)
3075 auto name {
static_cast<gchar*
>(user_data)};
3082 return (
Account*)account_foreach_descendant_breadthfirst_until (parent, is_acct_code, (
char*)code);
3086 is_opening_balance_account (
Account* account, gpointer data)
3088 gnc_commodity* commodity = GNC_COMMODITY(data);
3105 gnc_account_lookup_by_full_name_helper (
const Account *parent,
3108 g_return_val_if_fail(GNC_IS_ACCOUNT(parent),
nullptr);
3109 g_return_val_if_fail(names,
nullptr);
3112 for (
auto account : GET_PRIVATE(parent)->children)
3114 auto priv = GET_PRIVATE(account);
3115 if (g_strcmp0(priv->accountName, names[0]) == 0)
3119 if (names[1] ==
nullptr)
3123 if (priv->children.empty())
3127 if (
auto found = gnc_account_lookup_by_full_name_helper(account, &names[1]))
3145 g_return_val_if_fail(GNC_IS_ACCOUNT(any_acc),
nullptr);
3146 g_return_val_if_fail(name,
nullptr);
3149 rpriv = GET_PRIVATE(root);
3150 while (rpriv->parent)
3152 root = rpriv->parent;
3153 rpriv = GET_PRIVATE(root);
3156 found = gnc_account_lookup_by_full_name_helper(root, names);
3165 gnc_commodity* commodity)
3168 auto rpriv{GET_PRIVATE(root)};
3169 for (
auto account : rpriv->children)
3181 retval = g_list_prepend(retval, account);
3186 for (
auto account : rpriv->children)
3193 retval = g_list_concat(result, retval);
3203 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3204 g_return_if_fail(thunk);
3205 std::for_each (GET_PRIVATE(acc)->children.begin(), GET_PRIVATE(acc)->children.end(),
3206 [user_data, thunk](
auto a){ thunk (a, user_data); });
3222 gpointer result {
nullptr};
3224 g_return_val_if_fail (GNC_IS_ACCOUNT(acc),
nullptr);
3225 g_return_val_if_fail (thunk,
nullptr);
3227 for (
auto child : GET_PRIVATE(acc)->children)
3229 result = thunk (child, user_data);
3244 return GET_PRIVATE(acc)->type;
3248 qofAccountGetTypeString (
const Account *acc)
3250 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3255 qofAccountSetType (
Account *acc,
const char *type_string)
3257 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3258 g_return_if_fail(type_string);
3265 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3266 return GET_PRIVATE(acc)->accountName;
3269 std::vector<const Account*>
3270 gnc_account_get_all_parents (
const Account *account)
3272 std::vector<const Account*> rv;
3283 if (
nullptr == account)
3284 return g_strdup(
"");
3287 g_return_val_if_fail(GNC_IS_ACCOUNT(account), g_strdup(
""));
3289 auto path{gnc_account_get_all_parents (account)};
3290 auto seps_size{path.empty() ? 0 : strlen (account_separator) * (path.size() - 1)};
3291 auto alloc_size{std::accumulate (path.begin(), path.end(), seps_size,
3292 [](
auto sum,
auto acc)
3294 auto rv = g_new (
char, alloc_size + 1);
3297 std::for_each (path.rbegin(), path.rend(),
3301 p = stpcpy (p, account_separator);
3312 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3313 return GET_PRIVATE(acc)->accountCode;
3319 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3320 return GET_PRIVATE(acc)->description;
3326 return get_kvp_string_path (acc, {
"color"});
3332 return get_kvp_string_path (acc, {
"filter"});
3338 return get_kvp_string_path (acc, {
"sort-order"});
3344 return get_kvp_boolean_path (acc, {
"sort-reversed"});
3350 return get_kvp_string_path (acc, {
"notes"});
3356 g_return_val_if_fail (tag && *tag,
nullptr);
3358 return get_kvp_account_path (acc, {
"associated-account", tag});
3365 if (
auto s = get_kvp_string_path (acc, {
"old-currency"}))
3368 return gnc_commodity_table_lookup_unique (
table, s);
3377 if (!GNC_IS_ACCOUNT(acc))
3379 return GET_PRIVATE(acc)->commodity;
3384 g_return_val_if_fail (GNC_IS_ACCOUNT (account),
nullptr);
3400 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3402 priv = GET_PRIVATE(acc);
3403 priv->starting_balance = start_baln;
3404 priv->balance_dirty = TRUE;
3409 const gnc_numeric start_baln)
3413 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3415 priv = GET_PRIVATE(acc);
3416 priv->starting_cleared_balance = start_baln;
3417 priv->balance_dirty = TRUE;
3422 const gnc_numeric start_baln)
3426 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3428 priv = GET_PRIVATE(acc);
3429 priv->starting_reconciled_balance = start_baln;
3430 priv->balance_dirty = TRUE;
3436 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3437 return GET_PRIVATE(acc)->balance;
3443 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3444 return GET_PRIVATE(acc)->cleared_balance;
3450 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3451 return GET_PRIVATE(acc)->reconciled_balance;
3455 xaccAccountGetProjectedMinimumBalance (
const Account *acc)
3458 std::optional<gnc_numeric> minimum;
3460 auto before_today_end = [&minimum, today](
const Split *s) ->
bool 3470 return minimum ? *minimum : gnc_numeric_zero();
3478 GetBalanceAsOfDate (
Account *acc,
time64 date, std::function<gnc_numeric(Split*)> split_to_numeric)
3480 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3485 auto is_before_date = [date](
auto s) ->
bool 3489 return latest_split ? split_to_numeric (latest_split) : gnc_numeric_zero();
3499 xaccAccountGetNoclosingBalanceAsOfDate (
Account *acc,
time64 date)
3514 xaccAccountGetPresentBalance (
const Account *acc)
3516 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3533 xaccAccountConvertBalanceToCurrency(
const Account *acc,
3534 gnc_numeric balance,
3535 const gnc_commodity *balance_currency,
3536 const gnc_commodity *new_currency)
3545 book = gnc_account_get_book (acc);
3549 pdb, balance, balance_currency, new_currency);
3559 xaccAccountConvertBalanceToCurrencyAsOfDate(
const Account *acc,
3560 gnc_numeric balance,
3561 const gnc_commodity *balance_currency,
3562 const gnc_commodity *new_currency,
3572 book = gnc_account_get_book (acc);
3576 pdb, balance, balance_currency, new_currency, date);
3587 xaccAccountGetXxxBalanceInCurrency (
const Account *acc,
3588 xaccGetBalanceFn fn,
3589 const gnc_commodity *report_currency)
3592 gnc_numeric balance;
3594 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3595 g_return_val_if_fail(fn, gnc_numeric_zero());
3596 g_return_val_if_fail(GNC_IS_COMMODITY(report_currency), gnc_numeric_zero());
3598 priv = GET_PRIVATE(acc);
3600 balance = xaccAccountConvertBalanceToCurrency(acc, balance,
3607 xaccAccountGetXxxBalanceAsOfDateInCurrency(
Account *acc,
time64 date,
3608 xaccGetBalanceAsOfDateFn fn,
3609 const gnc_commodity *report_commodity)
3613 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3614 g_return_val_if_fail(fn, gnc_numeric_zero());
3615 g_return_val_if_fail(GNC_IS_COMMODITY(report_commodity), gnc_numeric_zero());
3617 priv = GET_PRIVATE(acc);
3618 return xaccAccountConvertBalanceToCurrencyAsOfDate(
3619 acc, fn(acc, date), priv->commodity, report_commodity, date);
3627 const gnc_commodity *currency;
3628 gnc_numeric balance;
3629 xaccGetBalanceFn fn;
3630 xaccGetBalanceAsOfDateFn asOfDateFn;
3641 xaccAccountBalanceHelper (
Account *acc, gpointer data)
3644 gnc_numeric balance;
3646 if (!cb->fn || !cb->currency)
3648 balance = xaccAccountGetXxxBalanceInCurrency (acc, cb->fn, cb->currency);
3655 xaccAccountBalanceAsOfDateHelper (
Account *acc, gpointer data)
3658 gnc_numeric balance;
3660 g_return_if_fail (cb->asOfDateFn && cb->currency);
3662 balance = xaccAccountGetXxxBalanceAsOfDateInCurrency (
3663 acc, cb->date, cb->asOfDateFn, cb->currency);
3682 xaccAccountGetXxxBalanceInCurrencyRecursive (
const Account *acc,
3683 xaccGetBalanceFn fn,
3684 const gnc_commodity *report_commodity,
3685 gboolean include_children)
3687 gnc_numeric balance;
3689 if (!acc)
return gnc_numeric_zero ();
3690 if (!report_commodity)
3692 if (!report_commodity)
3693 return gnc_numeric_zero();
3695 balance = xaccAccountGetXxxBalanceInCurrency (acc, fn, report_commodity);
3699 if (include_children)
3706 cb.balance = balance;
3712 balance = cb.balance;
3719 xaccAccountGetXxxBalanceAsOfDateInCurrencyRecursive (
3721 const gnc_commodity *report_commodity, gboolean include_children)
3723 gnc_numeric balance;
3725 g_return_val_if_fail(acc, gnc_numeric_zero());
3726 if (!report_commodity)
3728 if (!report_commodity)
3729 return gnc_numeric_zero();
3731 balance = xaccAccountGetXxxBalanceAsOfDateInCurrency(
3732 acc, date, fn, report_commodity);
3736 if (include_children)
3743 cb.balance = balance;
3745 CurrencyBalance cb = { report_commodity, balance,
nullptr, fn, date };
3749 balance = cb.balance;
3756 xaccAccountGetBalanceInCurrency (
const Account *acc,
3757 const gnc_commodity *report_commodity,
3758 gboolean include_children)
3761 rc = xaccAccountGetXxxBalanceInCurrencyRecursive (
3763 PINFO(
" baln=%" G_GINT64_FORMAT
"/%" G_GINT64_FORMAT, rc.num, rc.denom);
3769 xaccAccountGetClearedBalanceInCurrency (
const Account *acc,
3770 const gnc_commodity *report_commodity,
3771 gboolean include_children)
3773 return xaccAccountGetXxxBalanceInCurrencyRecursive (
3779 xaccAccountGetReconciledBalanceInCurrency (
const Account *acc,
3780 const gnc_commodity *report_commodity,
3781 gboolean include_children)
3783 return xaccAccountGetXxxBalanceInCurrencyRecursive (
3789 xaccAccountGetPresentBalanceInCurrency (
const Account *acc,
3790 const gnc_commodity *report_commodity,
3791 gboolean include_children)
3793 return xaccAccountGetXxxBalanceAsOfDateInCurrencyRecursive (
3800 xaccAccountGetProjectedMinimumBalanceInCurrency (
3802 const gnc_commodity *report_commodity,
3803 gboolean include_children)
3805 return xaccAccountGetXxxBalanceInCurrencyRecursive (
3806 acc, xaccAccountGetProjectedMinimumBalance, report_commodity,
3813 gboolean include_children)
3815 return xaccAccountGetXxxBalanceAsOfDateInCurrencyRecursive (
3823 gboolean include_children)
3825 return xaccAccountGetXxxBalanceAsOfDateInCurrencyRecursive
3826 (acc, date, xaccAccountGetNoclosingBalanceAsOfDate,
3827 report_commodity, include_children);
3842 xaccAccountGetNoclosingBalanceChangeForPeriod (
Account *acc,
time64 t1,
3843 time64 t2, gboolean recurse)
3854 const gnc_commodity *currency;
3855 gnc_numeric balanceChange;
3861 xaccAccountBalanceChangeHelper (
Account *acc, gpointer data)
3869 gnc_numeric balanceChange_conv = xaccAccountConvertBalanceToCurrencyAsOfDate(acc, balanceChange,
xaccAccountGetCommodity(acc), cbdiff->currency, cbdiff->t2);
3870 cbdiff->balanceChange =
gnc_numeric_add (cbdiff->balanceChange, balanceChange_conv,
3876 xaccAccountGetNoclosingBalanceChangeInCurrencyForPeriod (
Account *acc,
time64 t1,
3877 time64 t2, gboolean recurse)
3892 balanceChange = cbdiff.balanceChange;
3894 return balanceChange;
3901 xaccAccountGetSplits (
const Account *account)
3903 static const SplitsVec empty;
3904 g_return_val_if_fail (GNC_IS_ACCOUNT(account), empty);
3905 return GET_PRIVATE(account)->splits;
3911 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3912 auto priv{GET_PRIVATE(acc)};
3913 return std::accumulate (priv->splits.rbegin(), priv->splits.rend(),
3914 static_cast<GList*
>(
nullptr), g_list_prepend);
3918 xaccAccountGetSplitsSize (
const Account *account)
3920 g_return_val_if_fail (GNC_IS_ACCOUNT(account), 0);
3921 return GNC_IS_ACCOUNT(account) ? GET_PRIVATE(account)->splits.size() : 0;
3924 gboolean gnc_account_and_descendants_empty (
Account *acc)
3926 g_return_val_if_fail (GNC_IS_ACCOUNT (acc), FALSE);
3927 auto priv = GET_PRIVATE (acc);
3928 if (!priv->splits.empty())
return FALSE;
3929 return std::all_of (priv->children.begin(), priv->children.end(),
3930 gnc_account_and_descendants_empty);
3936 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3937 return g_list_copy(GET_PRIVATE(acc)->lots);
3942 gboolean (*match_func)(GNCLot *lot,
3943 gpointer user_data),
3944 gpointer user_data, GCompareFunc sort_func)
3948 GList *retval =
nullptr;
3950 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3952 priv = GET_PRIVATE(acc);
3953 for (lot_list = priv->lots; lot_list; lot_list = lot_list->next)
3955 GNCLot *lot =
static_cast<GNCLot*
>(lot_list->data);
3961 if (match_func && !(match_func)(lot, user_data))
3965 retval = g_list_prepend (retval, lot);
3969 retval = g_list_sort (retval, sort_func);
3976 gpointer (*proc)(GNCLot *lot,
void *data),
void *data)
3978 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3979 g_return_val_if_fail(proc,
nullptr);
3981 for (
auto node = GET_PRIVATE(acc)->lots; node; node = node->next)
3982 if (
auto result = proc(GNC_LOT(node->data), data))
3996 return get_kvp_boolean_path(acc, {
"tax-related"});
4002 set_kvp_boolean_path(acc, {
"tax-related"}, tax_related);
4008 return get_kvp_string_path (acc, {
"tax-US",
"code"});
4014 set_kvp_string_path (acc, {
"tax-US",
"code"}, code);
4020 return get_kvp_string_path (acc, {
"tax-US",
"payer-name-source"});
4026 set_kvp_string_path (acc, {
"tax-US",
"payer-name-source"}, source);
4032 auto copy_number = get_kvp_int64_path (acc, {
"tax-US",
"copy-number"});
4033 return (copy_number && (*copy_number != 0)) ? *copy_number : 1;
4039 if (copy_number != 0)
4040 set_kvp_int64_path (acc, {
"tax-US",
"copy-number"}, copy_number);
4043 set_kvp_int64_path (acc, {
"tax-US",
"copy-number"}, std::nullopt);
4053 return _(dflt_acct_debit_str);
4055 auto result = gnc_acct_debit_strs.find(acct_type);
4056 if (result != gnc_acct_debit_strs.end())
4057 return _(result->second);
4059 return _(dflt_acct_debit_str);
4065 return _(dflt_acct_credit_str);
4067 auto result = gnc_acct_credit_strs.find(acct_type);
4068 if (result != gnc_acct_credit_strs.end())
4069 return _(result->second);
4071 return _(dflt_acct_credit_str);
4080 return get_kvp_boolean_path(acc, {
"placeholder"});
4086 set_kvp_boolean_path(acc, {
"placeholder"}, val);
4092 return get_kvp_boolean_path(acc, {
"import-append-text"});
4098 set_kvp_boolean_path(acc, {
"import-append-text"}, val);
4104 g_return_val_if_fail (GNC_IS_ACCOUNT(acc),
false);
4108 return !g_strcmp0 (get_kvp_string_path (acc, {
"equity-type"}),
"opening-balance");
4114 g_return_if_fail (GNC_IS_ACCOUNT(acc));
4117 set_kvp_string_path(acc, {
"equity-type"}, val ?
"opening-balance" :
nullptr);
4123 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), PLACEHOLDER_NONE);
4127 ? PLACEHOLDER_CHILD : PLACEHOLDER_NONE;
4136 return get_kvp_boolean_path (acc, {KEY_RECONCILE_INFO,
"auto-interest-transfer"});
4142 set_kvp_boolean_path (acc, {KEY_RECONCILE_INFO,
"auto-interest-transfer"}, val);
4151 return get_kvp_boolean_path (acc, {
"hidden"});
4157 set_kvp_boolean_path (acc, {
"hidden"}, val);
4165 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4169 priv = GET_PRIVATE(acc);
4170 while ((acc = priv->parent) !=
nullptr)
4172 priv = GET_PRIVATE(acc);
4187 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4188 g_return_val_if_fail(GNC_IS_ACCOUNT(ancestor), FALSE);
4191 while (parent && parent != ancestor)
4192 parent = GET_PRIVATE(parent)->parent;
4194 return (parent == ancestor);
4203 #define GNC_RETURN_ENUM_AS_STRING(x) case (ACCT_TYPE_ ## x): return #x; 4210 GNC_RETURN_ENUM_AS_STRING(NONE);
4211 GNC_RETURN_ENUM_AS_STRING(BANK);
4212 GNC_RETURN_ENUM_AS_STRING(CASH);
4213 GNC_RETURN_ENUM_AS_STRING(CREDIT);
4214 GNC_RETURN_ENUM_AS_STRING(ASSET);
4215 GNC_RETURN_ENUM_AS_STRING(LIABILITY);
4216 GNC_RETURN_ENUM_AS_STRING(STOCK);
4217 GNC_RETURN_ENUM_AS_STRING(MUTUAL);
4218 GNC_RETURN_ENUM_AS_STRING(CURRENCY);
4219 GNC_RETURN_ENUM_AS_STRING(INCOME);
4220 GNC_RETURN_ENUM_AS_STRING(EXPENSE);
4221 GNC_RETURN_ENUM_AS_STRING(EQUITY);
4222 GNC_RETURN_ENUM_AS_STRING(RECEIVABLE);
4223 GNC_RETURN_ENUM_AS_STRING(PAYABLE);
4224 GNC_RETURN_ENUM_AS_STRING(ROOT);
4225 GNC_RETURN_ENUM_AS_STRING(TRADING);
4226 GNC_RETURN_ENUM_AS_STRING(CHECKING);
4227 GNC_RETURN_ENUM_AS_STRING(SAVINGS);
4228 GNC_RETURN_ENUM_AS_STRING(MONEYMRKT);
4229 GNC_RETURN_ENUM_AS_STRING(CREDITLINE);
4231 PERR (
"asked to translate unknown account type %d.\n", type);
4237 #undef GNC_RETURN_ENUM_AS_STRING 4239 #define GNC_RETURN_ON_MATCH(x) \ 4240 if(g_strcmp0(#x, (str)) == 0) { *type = ACCT_TYPE_ ## x; return(TRUE); } 4246 GNC_RETURN_ON_MATCH(NONE);
4247 GNC_RETURN_ON_MATCH(BANK);
4248 GNC_RETURN_ON_MATCH(CASH);
4249 GNC_RETURN_ON_MATCH(CREDIT);
4250 GNC_RETURN_ON_MATCH(ASSET);
4251 GNC_RETURN_ON_MATCH(LIABILITY);
4252 GNC_RETURN_ON_MATCH(STOCK);
4253 GNC_RETURN_ON_MATCH(MUTUAL);
4254 GNC_RETURN_ON_MATCH(CURRENCY);
4255 GNC_RETURN_ON_MATCH(INCOME);
4256 GNC_RETURN_ON_MATCH(EXPENSE);
4257 GNC_RETURN_ON_MATCH(EQUITY);
4258 GNC_RETURN_ON_MATCH(RECEIVABLE);
4259 GNC_RETURN_ON_MATCH(PAYABLE);
4260 GNC_RETURN_ON_MATCH(ROOT);
4261 GNC_RETURN_ON_MATCH(TRADING);
4262 GNC_RETURN_ON_MATCH(CHECKING);
4263 GNC_RETURN_ON_MATCH(SAVINGS);
4264 GNC_RETURN_ON_MATCH(MONEYMRKT);
4265 GNC_RETURN_ON_MATCH(CREDITLINE);
4267 PERR(
"asked to translate unknown account type string %s.\n",
4268 str ? str :
"(null)");
4273 #undef GNC_RETURN_ON_MATCH 4319 return _(account_type_name [type]);
4361 PERR(
"bad account type: %d", type);
4407 PERR(
"bad account type: %d", type);
4514 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4516 priv = GET_PRIVATE(acc);
4527 gboolean retval = FALSE;
4528 auto date = get_kvp_int64_path (acc, {KEY_RECONCILE_INFO,
"last-date"});
4545 set_kvp_int64_path (acc, {KEY_RECONCILE_INFO,
"last-date"}, last_date);
4553 int *months,
int *days)
4555 if (!acc)
return FALSE;
4556 auto m{get_kvp_int64_path (acc, {KEY_RECONCILE_INFO,
"last-interval",
"months"})};
4557 auto d{get_kvp_int64_path (acc, {KEY_RECONCILE_INFO,
"last-interval",
"days"})};
4575 set_kvp_int64_path (acc, {KEY_RECONCILE_INFO,
"last-interval",
"months"}, months);
4576 set_kvp_int64_path (acc, {KEY_RECONCILE_INFO,
"last-interval",
"days"}, days);
4585 if (
auto date = get_kvp_int64_path (acc, {KEY_RECONCILE_INFO, KEY_POSTPONE,
"date"}))
4588 *postpone_date = *date;
4600 set_kvp_int64_path (acc, {KEY_RECONCILE_INFO, KEY_POSTPONE,
"date"}, postpone_date);
4608 gnc_numeric *balance)
4610 if (
auto bal = get_kvp_gnc_numeric_path (acc, {KEY_RECONCILE_INFO, KEY_POSTPONE,
"balance"}))
4625 set_kvp_gnc_numeric_path (acc, {KEY_RECONCILE_INFO, KEY_POSTPONE,
"balance"}, balance);
4635 set_kvp_gnc_numeric_path (acc, {KEY_RECONCILE_INFO, KEY_POSTPONE}, {});
4644 return get_kvp_string_path (acc, {
"last-num"});
4653 set_kvp_string_path (acc, {
"last-num"}, num);
4661 get_balance_limit (
const Account* acc,
const std::string& key, gnc_numeric* balance)
4663 auto limit = get_kvp_gnc_numeric_path (acc, {KEY_BALANCE_LIMIT, key});
4665 *balance = gnc_numeric_create (limit->num, limit->denom);
4666 return limit.has_value();
4670 set_balance_limit (
Account *acc,
const std::string& key, std::optional<gnc_numeric> balance)
4674 set_kvp_gnc_numeric_path (acc, {KEY_BALANCE_LIMIT, key}, balance);
4679 gnc_numeric *balance)
4681 return get_balance_limit (acc, KEY_BALANCE_HIGHER_LIMIT_VALUE, balance);
4686 gnc_numeric *balance)
4688 return get_balance_limit (acc, KEY_BALANCE_LOWER_LIMIT_VALUE, balance);
4694 set_balance_limit (acc, KEY_BALANCE_HIGHER_LIMIT_VALUE, balance);
4700 set_balance_limit (acc, KEY_BALANCE_LOWER_LIMIT_VALUE, balance);
4706 set_balance_limit (acc, KEY_BALANCE_HIGHER_LIMIT_VALUE, {});
4712 set_balance_limit (acc, KEY_BALANCE_LOWER_LIMIT_VALUE, {});
4718 return get_kvp_boolean_path (acc, {KEY_BALANCE_LIMIT, KEY_BALANCE_INCLUDE_SUB_ACCTS});
4724 set_kvp_boolean_path (acc, {KEY_BALANCE_LIMIT, KEY_BALANCE_INCLUDE_SUB_ACCTS}, inc_sub);
4731 GetOrMakeOrphanAccount (
Account *root, gnc_commodity * currency)
4736 g_return_val_if_fail (root,
nullptr);
4741 PERR (
"No currency specified!");
4745 accname = g_strconcat (_(
"Orphaned Gains"),
"-",
4761 _(
"Realized Gains or Losses from " 4762 "Commodity or Trading Accounts " 4763 "that haven't been recorded elsewhere."));
4779 auto gains_account = get_kvp_account_path (acc, path);
4781 if (gains_account ==
nullptr)
4784 set_kvp_account_path (acc, path, gains_account);
4787 return gains_account;
4799 set_kvp_string_path (acc, {
"old-price-source"}, src);
4808 if (!acc)
return nullptr;
4812 return get_kvp_string_path (acc, {
"old-price-source"});
4823 set_kvp_string_path (acc, {
"old-quote-tz"}, tz);
4832 if (!acc)
return nullptr;
4834 return get_kvp_string_path (acc, {
"old-quote-tz"});
4847 set_kvp_int64_path (acc, {KEY_RECONCILE_INFO, KEY_INCLUDE_CHILDREN}, status);
4860 return get_kvp_boolean_path (acc, {KEY_RECONCILE_INFO, KEY_INCLUDE_CHILDREN});
4869 auto has_description = [description](
const Split* s) ->
bool 4894 g_return_if_fail(GNC_IS_ACCOUNT(to_parent));
4895 g_return_if_fail(GNC_IS_ACCOUNT(from_parent));
4898 auto from_priv = GET_PRIVATE(from_parent);
4899 if (from_priv->children.empty())
4903 auto children = from_priv->children;
4904 for (
auto child : children)
4914 g_return_if_fail(GNC_IS_ACCOUNT(parent));
4916 auto ppriv = GET_PRIVATE(parent);
4917 for (
auto it_a = ppriv->children.begin(); it_a != ppriv->children.end(); it_a++)
4920 auto priv_a = GET_PRIVATE(acc_a);
4921 for (
auto it_b = std::next(it_a); it_b != ppriv->children.end(); it_b++)
4924 auto priv_b = GET_PRIVATE(acc_b);
4925 if (0 !=
null_strcmp(priv_a->accountName, priv_b->accountName))
4927 if (0 !=
null_strcmp(priv_a->accountCode, priv_b->accountCode))
4929 if (0 !=
null_strcmp(priv_a->description, priv_b->description))
4939 if (priv_a->type != priv_b->type)
4943 if (!priv_b->children.empty())
4945 auto work = priv_b->children;
4957 while (!priv_b->splits.empty())
4958 xaccSplitSetAccount (priv_b->splits.front(), acc_a);
4977 xaccSplitsBeginStagedTransactionTraversals (SplitsVec& splits)
4979 for (
auto s : splits)
4981 Transaction *trans = s->parent;
4994 xaccSplitsBeginStagedTransactionTraversals(GET_PRIVATE (account)->splits);
5000 if (trans ==
nullptr)
return FALSE;
5002 if (trans->marker < stage)
5004 trans->marker = stage;
5015 auto do_one_account = [](
auto acc)
5016 { gnc_account_foreach_split (acc, [](
auto s){ s->parent->marker = 0; }); };
5023 TransactionCallback thunk,
5029 auto splits = GET_PRIVATE(acc)->splits;
5030 for (
auto s : splits)
5032 auto trans = s->parent;
5033 if (trans && (trans->marker < stage))
5035 trans->marker = stage;
5038 auto retval = thunk(trans, cb_data);
5039 if (retval)
return retval;
5050 TransactionCallback thunk,
5060 priv = GET_PRIVATE(acc);
5061 for (
auto acc_p : priv->children)
5064 if (retval)
return retval;
5068 for (
auto s : priv->splits)
5071 if (trans && (trans->marker < stage))
5073 trans->marker = stage;
5076 retval = thunk(trans, cb_data);
5077 if (retval)
return retval;
5088 g_return_val_if_fail (GNC_IS_ACCOUNT(account), INT64_MAX);
5089 const auto& splits = xaccAccountGetSplits (account);
5098 int (*proc)(Transaction *t,
void *data),
5101 if (!acc || !proc)
return 0;
5112 if (!acc || !proc)
return 0;
5123 #define IMAP_FRAME "import-map" 5124 #define IMAP_FRAME_BAYES "import-map-bayes" 5128 gnc_account_imap_find_account (
Account *acc,
5129 const char *category,
5132 if (!acc || !key)
return nullptr;
5133 std::vector<std::string> path {IMAP_FRAME};
5135 path.push_back (category);
5136 path.push_back (key);
5137 return get_kvp_account_path (acc, path);
5141 gnc_account_imap_find_any (QofBook *book,
const char* category,
const char *key)
5146 auto root = gnc_book_get_root_account (book);
5150 for (
auto ptr = accts; ptr; ptr = g_list_next (ptr))
5152 auto tmp_acc =
static_cast<Account*
> (ptr->data);
5154 if (gnc_account_imap_find_account (tmp_acc, category, key))
5160 g_list_free (accts);
5167 gnc_account_imap_add_account (
Account *acc,
5168 const char *category,
5172 if (!acc || !key || !added_acc || !*key)
return;
5174 auto path = category ? Path{IMAP_FRAME, category, key} : Path{IMAP_FRAME, key};
5176 set_kvp_account_path (acc, path, added_acc);
5181 gnc_account_imap_delete_account (
Account *acc,
5182 const char *category,
5185 if (!acc || !key)
return;
5187 auto path = category ? Path{IMAP_FRAME, category, key} : Path{IMAP_FRAME, key};
5188 if (qof_instance_has_path_slot (QOF_INSTANCE (acc), path))
5190 qof_instance_slot_path_delete (QOF_INSTANCE (acc), path);
5192 qof_instance_slot_path_delete_if_empty (QOF_INSTANCE (acc), {IMAP_FRAME, category});
5193 qof_instance_slot_path_delete_if_empty (QOF_INSTANCE (acc), {IMAP_FRAME});
5195 qof_instance_set_dirty (QOF_INSTANCE (acc));
5210 double product_difference;
5215 std::string account_guid;
5216 int64_t token_count;
5224 std::vector<AccountTokenCount> accounts;
5225 int64_t total_count;
5233 std::string account_guid;
5234 int32_t probability;
5238 build_token_info(
char const * suffix, KvpValue * value,
TokenAccountsInfo & tokenInfo)
5242 tokenInfo.total_count += value->get<int64_t>();
5244 tokenInfo.accounts.emplace_back(
AccountTokenCount{std::string{suffix}, value->get<int64_t>()});
5251 static constexpr
int probability_factor = 100000;
5253 static FinalProbabilityVec
5254 build_probabilities(ProbabilityVec
const & first_pass)
5256 FinalProbabilityVec ret;
5257 for (
auto const & first_pass_prob : first_pass)
5259 auto const & account_probability = first_pass_prob.second;
5264 int32_t probability = (account_probability.product /
5265 (account_probability.product + account_probability.product_difference)) * probability_factor;
5266 ret.push_back({first_pass_prob.first, probability});
5272 highest_probability(FinalProbabilityVec
const & probabilities)
5274 AccountInfo ret {
"", std::numeric_limits<int32_t>::min()};
5275 for (
auto const & prob : probabilities)
5276 if (prob.second > ret.probability)
5281 static ProbabilityVec
5282 get_first_pass_probabilities(
Account* acc, GList * tokens)
5287 for (
auto current_token = tokens; current_token; current_token = current_token->next)
5290 auto path = std::string{IMAP_FRAME_BAYES
"/"} + static_cast <
char const *> (current_token->data) +
"/";
5291 qof_instance_foreach_slot_prefix (QOF_INSTANCE (acc), path, &build_token_info, tokenInfo);
5292 for (
auto const & current_account_token : tokenInfo.accounts)
5294 auto item = std::find_if(ret.begin(), ret.end(), [¤t_account_token]
5295 (std::pair<std::string, AccountProbability>
const & a) {
5296 return current_account_token.account_guid == a.first;
5298 if (item != ret.end())
5300 item->second.product = ((double)current_account_token.token_count /
5301 (
double)tokenInfo.total_count) * item->second.product;
5302 item->second.product_difference = ((
double)1 - ((double)current_account_token.token_count /
5303 (
double)tokenInfo.total_count)) * item->second.product_difference;
5309 new_probability.product = ((double)current_account_token.token_count /
5310 (
double)tokenInfo.total_count);
5311 new_probability.product_difference = 1 - (new_probability.product);
5312 ret.push_back({current_account_token.account_guid, std::move(new_probability)});
5320 look_for_old_separator_descendants (
Account *root, std::string
const & full_name,
const gchar *separator)
5322 GList *top_accounts, *ptr;
5326 PINFO(
"Incoming full_name is '%s', current separator is '%s'", full_name.c_str (), separator);
5328 for (ptr = top_accounts; ptr; ptr = g_list_next (ptr))
5332 if (g_str_has_prefix (full_name.c_str (), name))
5334 gint name_len = strlen (name);
5335 const gchar old_sep = full_name[name_len];
5336 if (!g_ascii_isalnum (old_sep))
5338 if (name_len > found_len)
5340 found_sep = full_name[name_len];
5341 found_len = name_len;
5346 g_list_free (top_accounts);
5347 std::string new_name {full_name};
5349 std::replace (new_name.begin (), new_name.end (), found_sep, *separator);
5350 PINFO (
"Return full_name is '%s'", new_name.c_str ());
5355 get_guid_from_account_name (
Account * root, std::string
const & name)
5360 auto temp_account_name = look_for_old_separator_descendants (root, name,
5365 return temp_guid.to_string ();
5369 convert_entry (KvpEntry entry,
Account* root)
5372 auto account_name = entry.first.back();
5373 if (!gnc::GUID::is_valid_guid (account_name))
5379 entry.first.pop_back();
5380 auto guid_str = get_guid_from_account_name (root, account_name);
5381 entry.first.emplace_back (guid_str);
5383 std::string new_key {std::accumulate (entry.first.begin(), entry.first.end(), std::string {})};
5384 new_key = IMAP_FRAME_BAYES + new_key;
5385 return {new_key, entry.second};
5388 static std::vector<FlatKvpEntry>
5391 auto frame = qof_instance_get_slots (QOF_INSTANCE (acc));
5392 auto slot = frame->get_slot ({IMAP_FRAME_BAYES});
5395 auto imap_frame = slot->get<KvpFrame*> ();
5396 auto flat_kvp = imap_frame->flatten_kvp ();
5398 std::vector <FlatKvpEntry> ret;
5399 for (
auto const & flat_entry : flat_kvp)
5401 auto converted_entry = convert_entry (flat_entry, root);
5403 if (converted_entry.first.size())
5404 ret.emplace_back (converted_entry);
5410 convert_imap_account_bayes_to_flat (
Account *acc)
5412 auto frame = qof_instance_get_slots (QOF_INSTANCE (acc));
5413 if (!frame->get_keys().size())
5415 auto flat_imap = get_flat_imap(acc);
5416 if (!flat_imap.size ())
5419 frame->set({IMAP_FRAME_BAYES},
nullptr);
5420 std::for_each(flat_imap.begin(), flat_imap.end(),
5421 [&frame] (FlatKvpEntry
const & entry) {
5422 frame->set({entry.first.c_str()}, entry.second);
5424 qof_instance_set_dirty (QOF_INSTANCE (acc));
5433 imap_convert_bayes_to_flat (QofBook * book)
5435 auto root = gnc_book_get_root_account (book);
5438 for (
auto ptr = accts; ptr; ptr = g_list_next (ptr))
5441 if (convert_imap_account_bayes_to_flat (acc))
5447 g_list_free (accts);
5454 imap_convert_bayes_to_flat_run =
false;
5469 check_import_map_data (QofBook *book)
5471 if (gnc_features_check_used (book, GNC_FEATURE_GUID_FLAT_BAYESIAN) ||
5472 imap_convert_bayes_to_flat_run)
5476 imap_convert_bayes_to_flat (book);
5477 imap_convert_bayes_to_flat_run =
true;
5480 static constexpr
double threshold = .90 * probability_factor;
5488 auto book = gnc_account_get_book(acc);
5489 check_import_map_data (book);
5490 auto first_pass = get_first_pass_probabilities(acc, tokens);
5491 if (!first_pass.size())
5493 auto final_probabilities = build_probabilities(first_pass);
5494 if (!final_probabilities.size())
5496 auto best = highest_probability(final_probabilities);
5497 if (best.account_guid ==
"")
5499 if (best.probability < threshold)
5503 guid = gnc::GUID::from_string(best.account_guid);
5512 change_imap_entry (
Account *acc, std::string
const & path, int64_t token_count)
5514 PINFO(
"Source Account is '%s', Count is '%" G_GINT64_FORMAT
"'",
5518 if (
auto existing_token_count = get_kvp_int64_path (acc, {path}))
5520 PINFO(
"found existing value of '%" G_GINT64_FORMAT
"'", *existing_token_count);
5521 token_count += *existing_token_count;
5525 set_kvp_int64_path (acc, {path}, token_count);
5534 GList *current_token;
5536 char *account_fullname;
5545 check_import_map_data (gnc_account_get_book(acc));
5547 g_return_if_fail (added_acc !=
nullptr);
5551 PINFO(
"account name: '%s'", account_fullname);
5556 for (current_token = g_list_first(tokens); current_token;
5557 current_token = current_token->next)
5559 char* token =
static_cast<char*
>(current_token->data);
5564 if (!token || !token[0])
5568 PINFO(
"adding token '%s'", token);
5569 auto path = std::string {IMAP_FRAME_BAYES} +
'/' + token +
'/' + guid_string;
5571 change_imap_entry (acc, path, token_count);
5576 g_free (account_fullname);
5577 g_free (guid_string);
5584 build_non_bayes (
const char *key,
const GValue *value, gpointer user_data)
5586 if (!G_VALUE_HOLDS_BOXED (value))
5590 gchar *guid_string =
nullptr;
5595 guid = (
GncGUID*)g_value_get_boxed (value);
5598 PINFO(
"build_non_bayes: match string '%s', match account guid: '%s'",
5599 (
char*)key, guid_string);
5603 imapInfo_node->source_account = imapInfo->source_account;
5605 imapInfo_node->head = g_strdup (imapInfo->head);
5606 imapInfo_node->match_string = g_strdup (key);
5607 imapInfo_node->category = g_strdup (imapInfo->category);
5608 imapInfo_node->count = g_strdup (
" ");
5610 imapInfo->list = g_list_prepend (imapInfo->list, imapInfo_node);
5612 g_free (guid_string);
5616 build_bayes (
const char *suffix, KvpValue * value,
GncImapInfo & imapInfo)
5619 std::string account_guid {&suffix[guid_start]};
5623 guid = gnc::GUID::from_string (account_guid);
5627 PWARN(
"Invalid GUID string from %s%s", IMAP_FRAME_BAYES, suffix);
5629 auto map_account =
xaccAccountLookup (&guid, gnc_account_get_book (imapInfo.source_account));
5631 auto count = value->get <int64_t> ();
5632 imap_node->source_account = imapInfo.source_account;
5633 imap_node->map_account = map_account;
5634 imap_node->head = g_strdup_printf (
"%s%s", IMAP_FRAME_BAYES, suffix);
5635 imap_node->match_string = g_strndup (&suffix[1], guid_start - 2);
5636 imap_node->category = g_strdup(
" ");
5637 imap_node->count = g_strdup_printf (
"%" G_GINT64_FORMAT, count);
5638 imapInfo.list = g_list_prepend (imapInfo.list, imap_node);
5643 g_free (imapInfo->head);
5644 g_free (imapInfo->category);
5645 g_free (imapInfo->match_string);
5646 g_free (imapInfo->count);
5653 check_import_map_data (gnc_account_get_book (acc));
5657 qof_instance_foreach_slot_prefix (QOF_INSTANCE (acc), IMAP_FRAME_BAYES, &build_bayes, imapInfo);
5658 return g_list_reverse(imapInfo.list);
5664 GList *list =
nullptr;
5668 std::vector<std::string> path {IMAP_FRAME};
5670 path.emplace_back (category);
5672 imapInfo.source_account = acc;
5673 imapInfo.list = list;
5675 imapInfo.head = g_strdup (IMAP_FRAME);
5676 imapInfo.category = g_strdup (category);
5678 if (qof_instance_has_path_slot (QOF_INSTANCE (acc), path))
5680 qof_instance_foreach_slot (QOF_INSTANCE(acc), IMAP_FRAME, category,
5681 build_non_bayes, &imapInfo);
5683 g_free (imapInfo.head);
5684 g_free (imapInfo.category);
5685 return g_list_reverse(imapInfo.list);
5693 return g_strdup (category ?
5694 get_kvp_string_path (acc, {head, category}) :
5695 get_kvp_string_path (acc, {head}));
5702 get_kvp_guid_path (acc, {head, category}) :
5703 get_kvp_guid_path (acc, {head});
5708 char *match_string, gboolean empty)
5712 std::vector<std::string> path {head};
5714 path.emplace_back (category);
5716 path.emplace_back (match_string);
5718 if (qof_instance_has_path_slot (QOF_INSTANCE (acc), path))
5722 qof_instance_slot_path_delete_if_empty (QOF_INSTANCE(acc), path);
5724 qof_instance_slot_path_delete (QOF_INSTANCE(acc), path);
5725 PINFO(
"Account is '%s', head is '%s', category is '%s', match_string is'%s'",
5727 qof_instance_set_dirty (QOF_INSTANCE(acc));
5738 auto slots = qof_instance_get_slots_prefix (QOF_INSTANCE (acc), IMAP_FRAME_BAYES);
5739 if (!slots.size())
return;
5741 for (
auto const & entry : slots)
5743 qof_instance_slot_path_delete (QOF_INSTANCE (acc), {entry.first});
5745 qof_instance_set_dirty (QOF_INSTANCE(acc));
5754 destroy_all_child_accounts (
Account *acc, gpointer data)
5761 gnc_account_book_end(QofBook* book)
5763 Account *root_account = gnc_book_get_root_account (book);
5773 accounts = g_list_reverse (accounts);
5774 g_list_foreach (accounts, (GFunc)destroy_all_child_accounts,
nullptr);
5775 g_list_free (accounts);
5788 static QofObject account_object_def =
5791 DI(.e_type = ) GNC_ID_ACCOUNT,
5794 DI(.book_begin = )
nullptr,
5795 DI(.book_end = ) gnc_account_book_end,
5798 DI(.foreach = ) qof_collection_foreach,
5803 gboolean xaccAccountRegister (
void)
5805 static QofParam params[] =
5808 ACCOUNT_NAME_, QOF_TYPE_STRING,
5813 ACCOUNT_CODE_, QOF_TYPE_STRING,
5818 ACCOUNT_DESCRIPTION_, QOF_TYPE_STRING,
5823 ACCOUNT_COLOR_, QOF_TYPE_STRING,
5828 ACCOUNT_FILTER_, QOF_TYPE_STRING,
5833 ACCOUNT_SORT_ORDER_, QOF_TYPE_STRING,
5838 ACCOUNT_SORT_REVERSED_, QOF_TYPE_BOOLEAN,
5843 ACCOUNT_NOTES_, QOF_TYPE_STRING,
5848 ACCOUNT_PRESENT_, QOF_TYPE_NUMERIC,
5852 ACCOUNT_BALANCE_, QOF_TYPE_NUMERIC,
5856 ACCOUNT_CLEARED_, QOF_TYPE_NUMERIC,
5860 ACCOUNT_RECONCILED_, QOF_TYPE_NUMERIC,
5864 ACCOUNT_TYPE_, QOF_TYPE_STRING,
5869 ACCOUNT_FUTURE_MINIMUM_, QOF_TYPE_NUMERIC,
5870 (
QofAccessFunc) xaccAccountGetProjectedMinimumBalance,
nullptr 5873 ACCOUNT_TAX_RELATED, QOF_TYPE_BOOLEAN,
5878 ACCOUNT_OPENING_BALANCE_, QOF_TYPE_BOOLEAN,
5883 ACCOUNT_SCU, QOF_TYPE_INT32,
5888 ACCOUNT_NSCU, QOF_TYPE_BOOLEAN,
5893 ACCOUNT_PARENT, GNC_ID_ACCOUNT,
5902 QOF_PARAM_GUID, QOF_TYPE_GUID,
5917 utest_account_get_private (
Account *acc)
5919 return GET_PRIVATE (acc);
5923 _utest_account_fill_functions(
void)
5927 func->get_private = utest_account_get_private;
5928 func->coll_get_root_account = gnc_coll_get_root_account;
5929 func->xaccFreeAccountChildren = xaccFreeAccountChildren;
5930 func->xaccFreeAccount = xaccFreeAccount;
5931 func->qofAccountSetParent = qofAccountSetParent;
5932 func->gnc_account_lookup_by_full_name_helper =
5933 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.
QOF event handling interface.
gint gnc_account_n_descendants(const Account *account)
Return the number of descendants of the specified account.
gint64 xaccAccountGetTaxUSCopyNumber(const Account *acc)
Returns copy_number stored in KVP; if KVP doesn't exist or copy_number is zero, returns 1...
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...
GncGUID * guid_copy(const GncGUID *guid)
Returns a newly allocated GncGUID that matches the passed-in GUID.
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.
gint 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.
void xaccTransDestroy(Transaction *trans)
Destroys a transaction.
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...
time64 gnc_account_get_earliest_date(const Account *account)
Returns the date of the earliest split in the account, or INT64_MAX.
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.
void xaccAccountDestroyAllTransactions(Account *acc)
Destroy all of the transactions that parent splits in an account.
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 qof_event_suspend(void)
Suspend all engine events.
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".
void qof_event_resume(void)
Resume engine event generation.
gint qof_instance_guid_compare(gconstpointer ptr1, gconstpointer ptr2)
Compare the GncGUID values of two instances.
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 a)
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...
GncGUID * gnc_account_get_map_guid_entry(Account *acc, const char *head, const char *category)
Returns the guid pointed to by head and category for the Account, free the returned guid...
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)
Saves copy_number in KVP if it is greater than 1; if copy_number is zero, deletes KVP...