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;
331 priv->has_stock_split =
false;
333 new (&priv->children) AccountVec ();
334 new (&priv->splits) SplitsVec ();
335 priv->splits_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
336 priv->sort_dirty = FALSE;
340 gnc_account_dispose (GObject *acctp)
342 G_OBJECT_CLASS(gnc_account_parent_class)->dispose(acctp);
346 gnc_account_finalize(GObject* acctp)
348 G_OBJECT_CLASS(gnc_account_parent_class)->finalize(acctp);
358 gnc_account_get_property (GObject *
object,
366 g_return_if_fail(GNC_IS_ACCOUNT(
object));
368 account = GNC_ACCOUNT(
object);
369 priv = GET_PRIVATE(account);
373 g_value_set_string(value, priv->accountName);
379 g_value_set_string(value, priv->accountCode);
381 case PROP_DESCRIPTION:
382 g_value_set_string(value, priv->description);
392 g_value_set_int(value, priv->type);
395 g_value_take_object(value, priv->commodity);
397 case PROP_COMMODITY_SCU:
398 g_value_set_int(value, priv->commodity_scu);
400 case PROP_NON_STD_SCU:
401 g_value_set_boolean(value, priv->non_standard_scu);
403 case PROP_SORT_DIRTY:
404 g_value_set_boolean(value, priv->sort_dirty);
406 case PROP_BALANCE_DIRTY:
407 g_value_set_boolean(value, priv->balance_dirty);
409 case PROP_START_BALANCE:
410 g_value_set_boxed(value, &priv->starting_balance);
412 case PROP_START_NOCLOSING_BALANCE:
413 g_value_set_boxed(value, &priv->starting_noclosing_balance);
415 case PROP_START_CLEARED_BALANCE:
416 g_value_set_boxed(value, &priv->starting_cleared_balance);
418 case PROP_START_RECONCILED_BALANCE:
419 g_value_set_boxed(value, &priv->starting_reconciled_balance);
421 case PROP_END_BALANCE:
422 g_value_set_boxed(value, &priv->balance);
424 case PROP_END_NOCLOSING_BALANCE:
425 g_value_set_boxed(value, &priv->noclosing_balance);
427 case PROP_END_CLEARED_BALANCE:
428 g_value_set_boxed(value, &priv->cleared_balance);
430 case PROP_END_RECONCILED_BALANCE:
431 g_value_set_boxed(value, &priv->reconciled_balance);
435 g_value_set_pointer(value, priv->policy);
438 g_value_set_int(value, priv->mark);
440 case PROP_TAX_RELATED:
446 case PROP_TAX_SOURCE:
447 g_value_set_string(value,
450 case PROP_TAX_COPY_NUMBER:
451 g_value_set_int64(value,
457 case PROP_AUTO_INTEREST:
460 case PROP_IS_OPENING_BALANCE:
463 case PROP_PLACEHOLDER:
469 case PROP_SORT_ORDER:
472 case PROP_SORT_REVERSED:
475 case PROP_LOT_NEXT_ID:
477 g_value_set_int64 (value, 0);
478 qof_instance_get_path_kvp (QOF_INSTANCE (account), value, {KEY_LOT_MGMT,
"next-id"});
480 case PROP_ONLINE_ACCOUNT:
481 qof_instance_get_path_kvp (QOF_INSTANCE (account), value, {KEY_ONLINE_ID});
483 case PROP_IMP_APPEND_TEXT:
486 case PROP_OFX_INCOME_ACCOUNT:
487 qof_instance_get_path_kvp (QOF_INSTANCE (account), value, {KEY_ASSOC_INCOME_ACCOUNT});
489 case PROP_AB_ACCOUNT_ID:
490 qof_instance_get_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_ACCOUNT_ID});
492 case PROP_AB_ACCOUNT_UID:
493 qof_instance_get_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_ACCOUNT_UID});
495 case PROP_AB_BANK_CODE:
496 qof_instance_get_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_BANK_CODE});
498 case PROP_AB_TRANS_RETRIEVAL:
499 qof_instance_get_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_TRANS_RETRIEVAL});
502 G_OBJECT_WARN_INVALID_PROPERTY_ID(
object, prop_id, pspec);
508 gnc_account_set_property (GObject *
object,
515 g_return_if_fail(GNC_IS_ACCOUNT(
object));
516 account = GNC_ACCOUNT(
object);
517 if (prop_id < PROP_RUNTIME_0)
518 g_assert (qof_instance_get_editlevel(account));
528 case PROP_DESCRIPTION:
544 case PROP_COMMODITY_SCU:
547 case PROP_NON_STD_SCU:
550 case PROP_SORT_DIRTY:
553 case PROP_BALANCE_DIRTY:
556 case PROP_START_BALANCE:
557 number =
static_cast<gnc_numeric*
>(g_value_get_boxed(value));
560 case PROP_START_CLEARED_BALANCE:
561 number =
static_cast<gnc_numeric*
>(g_value_get_boxed(value));
564 case PROP_START_RECONCILED_BALANCE:
565 number =
static_cast<gnc_numeric*
>(g_value_get_boxed(value));
574 case PROP_TAX_RELATED:
580 case PROP_TAX_SOURCE:
582 g_value_get_string(value));
584 case PROP_TAX_COPY_NUMBER:
586 g_value_get_int64(value));
591 case PROP_AUTO_INTEREST:
594 case PROP_IS_OPENING_BALANCE:
597 case PROP_PLACEHOLDER:
603 case PROP_SORT_ORDER:
606 case PROP_SORT_REVERSED:
609 case PROP_LOT_NEXT_ID:
610 qof_instance_set_path_kvp (QOF_INSTANCE (account), value, {KEY_LOT_MGMT,
"next-id"});
612 case PROP_ONLINE_ACCOUNT:
613 qof_instance_set_path_kvp (QOF_INSTANCE (account), value, {KEY_ONLINE_ID});
615 case PROP_IMP_APPEND_TEXT:
618 case PROP_OFX_INCOME_ACCOUNT:
619 qof_instance_set_path_kvp (QOF_INSTANCE (account), value, {KEY_ASSOC_INCOME_ACCOUNT});
621 case PROP_AB_ACCOUNT_ID:
622 qof_instance_set_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_ACCOUNT_ID});
624 case PROP_AB_ACCOUNT_UID:
625 qof_instance_set_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_ACCOUNT_UID});
627 case PROP_AB_BANK_CODE:
628 qof_instance_set_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_BANK_CODE});
630 case PROP_AB_TRANS_RETRIEVAL:
631 qof_instance_set_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_TRANS_RETRIEVAL});
634 G_OBJECT_WARN_INVALID_PROPERTY_ID(
object, prop_id, pspec);
642 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
644 gobject_class->dispose = gnc_account_dispose;
645 gobject_class->finalize = gnc_account_finalize;
646 gobject_class->set_property = gnc_account_set_property;
647 gobject_class->get_property = gnc_account_get_property;
649 g_object_class_install_property
652 g_param_spec_string (
"name",
654 "The accountName is an arbitrary string " 655 "assigned by the user. It is intended to " 656 "a short, 5 to 30 character long string " 657 "that is displayed by the GUI as the " 658 "account mnemonic. Account names may be " 659 "repeated. but no two accounts that share " 660 "a parent may have the same name.",
662 static_cast<GParamFlags>(G_PARAM_READWRITE)));
664 g_object_class_install_property
667 g_param_spec_string (
"fullname",
669 "The name of the account concatenated with " 670 "all its parent account names to indicate " 673 static_cast<GParamFlags>(G_PARAM_READABLE)));
675 g_object_class_install_property
678 g_param_spec_string (
"code",
680 "The account code is an arbitrary string " 681 "assigned by the user. It is intended to " 682 "be reporting code that is a synonym for " 685 static_cast<GParamFlags>(G_PARAM_READWRITE)));
687 g_object_class_install_property
690 g_param_spec_string (
"description",
691 "Account Description",
692 "The account description is an arbitrary " 693 "string assigned by the user. It is intended " 694 "to be a longer, 1-5 sentence description of " 695 "what this account is all about.",
697 static_cast<GParamFlags>(G_PARAM_READWRITE)));
699 g_object_class_install_property
702 g_param_spec_string (
"color",
704 "The account color is a color string assigned " 705 "by the user. It is intended to highlight the " 706 "account based on the users wishes.",
708 static_cast<GParamFlags>(G_PARAM_READWRITE)));
710 g_object_class_install_property
713 g_param_spec_string (
"notes",
715 "The account notes is an arbitrary provided " 716 "for the user to attach any other text that " 717 "they would like to associate with the account.",
719 static_cast<GParamFlags>(G_PARAM_READWRITE)));
721 g_object_class_install_property
724 g_param_spec_int (
"type",
726 "The account type, picked from the enumerated list " 727 "that includes ACCT_TYPE_BANK, ACCT_TYPE_STOCK, " 728 "ACCT_TYPE_CREDIT, ACCT_TYPE_INCOME, etc.",
732 static_cast<GParamFlags>(G_PARAM_READWRITE)));
734 g_object_class_install_property
737 g_param_spec_object (
"commodity",
739 "The commodity field denotes the kind of " 740 "'stuff' stored in this account, whether " 741 "it is USD, gold, stock, etc.",
743 static_cast<GParamFlags>(G_PARAM_READWRITE)));
745 g_object_class_install_property
748 g_param_spec_int (
"commodity-scu",
750 "The smallest fraction of the commodity that is " 751 "tracked. This number is used as the denominator " 752 "value in 1/x, so a value of 100 says that the " 753 "commodity can be divided into hundredths. E.G." 754 "1 USD can be divided into 100 cents.",
758 static_cast<GParamFlags>(G_PARAM_READWRITE)));
760 g_object_class_install_property
763 g_param_spec_boolean (
"non-std-scu",
765 "TRUE if the account SCU doesn't match " 766 "the commodity SCU. This indicates a case " 767 "where the two were accidentally set to " 768 "mismatched values in older versions of " 771 static_cast<GParamFlags>(G_PARAM_READWRITE)));
773 g_object_class_install_property
776 g_param_spec_boolean(
"sort-dirty",
778 "TRUE if the splits in the account needs to be " 779 "resorted. This flag is set by the accounts " 780 "code for certain internal modifications, or " 781 "when external code calls the engine to say a " 782 "split has been modified in a way that may " 783 "affect the sort order of the account. Note: " 784 "This value can only be set to TRUE.",
786 static_cast<GParamFlags>(G_PARAM_READWRITE)));
788 g_object_class_install_property
791 g_param_spec_boolean(
"balance-dirty",
793 "TRUE if the running balances in the account " 794 "needs to be recalculated. This flag is set " 795 "by the accounts code for certain internal " 796 "modifications, or when external code calls " 797 "the engine to say a split has been modified. " 798 "Note: This value can only be set to TRUE.",
800 static_cast<GParamFlags>(G_PARAM_READWRITE)));
802 g_object_class_install_property
805 g_param_spec_boxed(
"start-balance",
807 "The starting balance for the account. This " 808 "parameter is intended for use with backends that " 809 "do not return the complete list of splits for an " 810 "account, but rather return a partial list. In " 811 "such a case, the backend will typically return " 812 "all of the splits after some certain date, and " 813 "the 'starting balance' will represent the " 814 "summation of the splits up to that date.",
816 static_cast<GParamFlags>(G_PARAM_READWRITE)));
818 g_object_class_install_property
820 PROP_START_NOCLOSING_BALANCE,
821 g_param_spec_boxed(
"start-noclosing-balance",
822 "Starting No-closing Balance",
823 "The starting balance for the account, ignoring closing." 824 "This parameter is intended for use with backends " 825 "that do not return the complete list of splits " 826 "for an account, but rather return a partial " 827 "list. In such a case, the backend will " 828 "typically return all of the splits after " 829 "some certain date, and the 'starting noclosing " 830 "balance' will represent the summation of the " 831 "splits up to that date, ignoring closing splits.",
833 static_cast<GParamFlags>(G_PARAM_READWRITE)));
835 g_object_class_install_property
837 PROP_START_CLEARED_BALANCE,
838 g_param_spec_boxed(
"start-cleared-balance",
839 "Starting Cleared Balance",
840 "The starting cleared balance for the account. " 841 "This parameter is intended for use with backends " 842 "that do not return the complete list of splits " 843 "for an account, but rather return a partial " 844 "list. In such a case, the backend will " 845 "typically return all of the splits after " 846 "some certain date, and the 'starting cleared " 847 "balance' will represent the summation of the " 848 "splits up to that date.",
850 static_cast<GParamFlags>(G_PARAM_READWRITE)));
852 g_object_class_install_property
854 PROP_START_RECONCILED_BALANCE,
855 g_param_spec_boxed(
"start-reconciled-balance",
856 "Starting Reconciled Balance",
857 "The starting reconciled balance for the " 858 "account. This parameter is intended for use " 859 "with backends that do not return the complete " 860 "list of splits for an account, but rather return " 861 "a partial list. In such a case, the backend " 862 "will typically return all of the splits after " 863 "some certain date, and the 'starting reconciled " 864 "balance' will represent the summation of the " 865 "splits up to that date.",
867 static_cast<GParamFlags>(G_PARAM_READWRITE)));
869 g_object_class_install_property
872 g_param_spec_boxed(
"end-balance",
873 "Ending Account Balance",
874 "This is the current ending balance for the " 875 "account. It is computed from the sum of the " 876 "starting balance and all splits in the account.",
880 g_object_class_install_property
882 PROP_END_NOCLOSING_BALANCE,
883 g_param_spec_boxed(
"end-noclosing-balance",
884 "Ending Account Noclosing Balance",
885 "This is the current ending no-closing balance for " 886 "the account. It is computed from the sum of the " 887 "starting balance and all cleared splits in the " 892 g_object_class_install_property
894 PROP_END_CLEARED_BALANCE,
895 g_param_spec_boxed(
"end-cleared-balance",
896 "Ending Account Cleared Balance",
897 "This is the current ending cleared balance for " 898 "the account. It is computed from the sum of the " 899 "starting balance and all cleared splits in the " 904 g_object_class_install_property
906 PROP_END_RECONCILED_BALANCE,
907 g_param_spec_boxed(
"end-reconciled-balance",
908 "Ending Account Reconciled Balance",
909 "This is the current ending reconciled balance " 910 "for the account. It is computed from the sum of " 911 "the starting balance and all reconciled splits " 914 static_cast<GParamFlags>(G_PARAM_READABLE)));
916 g_object_class_install_property
919 g_param_spec_pointer (
"policy",
921 "The account lots policy.",
922 static_cast<GParamFlags>(G_PARAM_READWRITE)));
924 g_object_class_install_property
927 g_param_spec_int (
"acct-mark",
933 static_cast<GParamFlags>(G_PARAM_READWRITE)));
935 g_object_class_install_property
938 g_param_spec_boolean (
"tax-related",
940 "Whether the account maps to an entry on an " 941 "income tax document.",
943 static_cast<GParamFlags>(G_PARAM_READWRITE)));
945 g_object_class_install_property
947 PROP_IS_OPENING_BALANCE,
948 g_param_spec_boolean (
"opening-balance",
950 "Whether the account holds opening balances",
952 static_cast<GParamFlags>(G_PARAM_READWRITE)));
954 g_object_class_install_property
957 g_param_spec_string (
"tax-code",
959 "This is the code for mapping an account to a " 960 "specific entry on a taxable document. In the " 961 "United States it is used to transfer totals " 962 "into tax preparation software.",
964 static_cast<GParamFlags>(G_PARAM_READWRITE)));
966 g_object_class_install_property
969 g_param_spec_string (
"tax-source",
971 "This specifies where exported name comes from.",
973 static_cast<GParamFlags>(G_PARAM_READWRITE)));
975 g_object_class_install_property
977 PROP_TAX_COPY_NUMBER,
978 g_param_spec_int64 (
"tax-copy-number",
980 "This specifies the copy number of the tax " 985 static_cast<GParamFlags>(G_PARAM_READWRITE)));
987 g_object_class_install_property
990 g_param_spec_boolean (
"hidden",
992 "Whether the account should be hidden in the " 995 static_cast<GParamFlags>(G_PARAM_READWRITE)));
997 g_object_class_install_property
1000 g_param_spec_boolean (
"auto-interest-transfer",
1002 "Whether an interest transfer should be automatically " 1003 "added before reconcile.",
1005 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1007 g_object_class_install_property
1010 g_param_spec_boolean (
"placeholder",
1012 "Whether the account is a placeholder account which does not " 1013 "allow transactions to be created, edited or deleted.",
1015 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1017 g_object_class_install_property
1020 g_param_spec_string (
"filter",
1022 "The account filter is a value saved to allow " 1023 "filters to be recalled.",
1025 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1027 g_object_class_install_property
1030 g_param_spec_string (
"sort-order",
1031 "Account Sort Order",
1032 "The account sort order is a value saved to allow " 1033 "the sort order to be recalled.",
1035 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1037 g_object_class_install_property
1040 g_param_spec_boolean (
"sort-reversed",
1041 "Account Sort Reversed",
1042 "Parameter to store whether the sort order is reversed or not.",
1044 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1046 g_object_class_install_property
1049 g_param_spec_int64 (
"lot-next-id",
1051 "Tracks the next id to use in gnc_lot_make_default.",
1055 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1057 g_object_class_install_property
1059 PROP_ONLINE_ACCOUNT,
1060 g_param_spec_string (
"online-id",
1061 "Online Account ID",
1062 "The online account which corresponds to this " 1063 "account for OFX import",
1065 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1067 g_object_class_install_property
1069 PROP_IMP_APPEND_TEXT,
1070 g_param_spec_boolean (
"import-append-text",
1071 "Import Append Text",
1072 "Saved state of Append checkbox for setting initial " 1073 "value next time this account is imported.",
1075 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1077 g_object_class_install_property(
1079 PROP_OFX_INCOME_ACCOUNT,
1080 g_param_spec_boxed(
"ofx-income-account",
1081 "Associated income account",
1082 "Used by the OFX importer.",
1084 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1086 g_object_class_install_property
1089 g_param_spec_string (
"ab-account-id",
1090 "AQBanking Account ID",
1091 "The AqBanking account which corresponds to this " 1092 "account for AQBanking import",
1094 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1095 g_object_class_install_property
1098 g_param_spec_string (
"ab-bank-code",
1099 "AQBanking Bank Code",
1100 "The online account which corresponds to this " 1101 "account for AQBanking import",
1103 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1105 g_object_class_install_property
1107 PROP_AB_ACCOUNT_UID,
1108 g_param_spec_int64 (
"ab-account-uid",
1109 "AQBanking Account UID",
1110 "Tracks the next id to use in gnc_lot_make_default.",
1114 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1116 g_object_class_install_property
1118 PROP_AB_TRANS_RETRIEVAL,
1119 g_param_spec_boxed(
"ab-trans-retrieval",
1120 "AQBanking Last Transaction Retrieval",
1121 "The time of the last transaction retrieval for this " 1124 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1131 ENTER (
"book=%p\n", book);
1134 LEAVE (
"account=%p\n", acc);
1141 gnc_account_foreach_split (
const Account *acc, std::function<
void(Split*)> func)
1143 if (!GNC_IS_ACCOUNT (acc))
1146 auto& splits{GET_PRIVATE(acc)->splits};
1147 std::for_each (splits.begin(), splits.end(), func);
1151 gnc_account_foreach_split_until_date (
const Account *acc,
time64 end_date,
1152 std::function<
void(Split*)> f)
1154 if (!GNC_IS_ACCOUNT (acc))
1157 auto after_date = [](
time64 end_date,
auto s) ->
bool 1160 auto& splits{GET_PRIVATE(acc)->splits};
1161 auto after_date_iter = std::upper_bound (splits.begin(), splits.end(), end_date, after_date);
1162 std::for_each (splits.begin(), after_date_iter, f);
1170 if (!GNC_IS_ACCOUNT (acc))
1173 const auto& splits{GET_PRIVATE(acc)->splits};
1176 auto latest = std::find_if(splits.rbegin(), splits.rend(), predicate);
1177 return (latest == splits.rend()) ?
nullptr : *latest;
1181 auto earliest = std::find_if(splits.begin(), splits.end(), predicate);
1182 return (earliest == splits.end()) ?
nullptr : *earliest;
1190 gnc_account_get_book(
const Account *account)
1192 if (!account)
return nullptr;
1200 gnc_coll_get_root_account (QofCollection *col)
1202 if (!col)
return nullptr;
1207 gnc_coll_set_root_account (QofCollection *col,
Account *root)
1213 old_root = gnc_coll_get_root_account (col);
1214 if (old_root == root)
return;
1219 rpriv = GET_PRIVATE(root);
1227 qof_collection_set_data (col, root);
1237 gnc_book_get_root_account (
QofBook *book)
1242 if (!book)
return nullptr;
1244 root = gnc_coll_get_root_account (col);
1256 if (root && gnc_account_get_book(root) != book)
1258 PERR (
"cannot mix and match books freely!");
1263 gnc_coll_set_root_account (col, root);
1274 g_return_val_if_fail (book,
nullptr);
1276 acc =
static_cast<Account*
>(g_object_new (GNC_TYPE_ACCOUNT,
nullptr));
1277 xaccInitAccount (acc, book);
1290 rpriv = GET_PRIVATE(root);
1294 mark_account (root);
1296 gnc_book_set_root_account(book, root);
1306 g_return_val_if_fail(GNC_IS_ACCOUNT(from),
nullptr);
1307 g_return_val_if_fail(QOF_IS_BOOK(book),
nullptr);
1310 ret =
static_cast<Account*
>(g_object_new (GNC_TYPE_ACCOUNT,
nullptr));
1311 g_return_val_if_fail (ret,
nullptr);
1313 from_priv = GET_PRIVATE(from);
1314 priv = GET_PRIVATE(ret);
1315 xaccInitAccount (ret, book);
1320 priv->type = from_priv->type;
1326 qof_instance_copy_kvp (QOF_INSTANCE (ret), QOF_INSTANCE (from));
1333 priv->commodity_scu = from_priv->commodity_scu;
1334 priv->non_standard_scu = from_priv->non_standard_scu;
1336 qof_instance_set_dirty(&ret->inst);
1345 xaccFreeOneChildAccount (
Account *acc)
1349 if (qof_instance_get_editlevel(acc) == 0)
1355 xaccFreeAccountChildren (
Account *acc)
1357 auto priv{GET_PRIVATE(acc)};
1359 auto children = priv->children;
1360 std::for_each (children.begin(), children.end(), xaccFreeOneChildAccount);
1363 priv->children.clear();
1371 xaccFreeAccount (
Account *acc)
1376 g_return_if_fail(GNC_IS_ACCOUNT(acc));
1378 priv = GET_PRIVATE(acc);
1385 qof_instance_set_destroying(acc, TRUE);
1387 if (!priv->children.empty())
1389 PERR (
" instead of calling xaccFreeAccount(), please call\n" 1390 " xaccAccountBeginEdit(); xaccAccountDestroy();\n");
1393 xaccFreeAccountChildren(acc);
1399 PERR (
" instead of calling xaccFreeAccount(), please call\n" 1400 " xaccAccountBeginEdit(); xaccAccountDestroy();\n");
1402 for (lp = priv->lots; lp; lp = lp->next)
1404 GNCLot *lot =
static_cast<GNCLot*
>(lp->data);
1405 gnc_lot_destroy (lot);
1407 g_list_free (priv->lots);
1408 priv->lots =
nullptr;
1415 if (!priv->splits.empty())
1417 PERR (
" instead of calling xaccFreeAccount(), please call\n" 1418 " xaccAccountBeginEdit(); xaccAccountDestroy();\n");
1420 qof_instance_reset_editlevel(acc);
1422 for (
auto s : priv->splits)
1435 priv->accountName = priv->accountCode = priv->description =
nullptr;
1440 priv->last_num =
nullptr;
1441 priv->tax_us_code =
nullptr;
1442 priv->tax_us_pns =
nullptr;
1443 priv->color =
nullptr;
1444 priv->sort_order =
nullptr;
1445 priv->notes =
nullptr;
1446 priv->filter =
nullptr;
1448 priv->parent =
nullptr;
1450 priv->balance = gnc_numeric_zero();
1451 priv->noclosing_balance = gnc_numeric_zero();
1452 priv->cleared_balance = gnc_numeric_zero();
1453 priv->reconciled_balance = gnc_numeric_zero();
1457 priv->commodity =
nullptr;
1459 priv->balance_dirty = FALSE;
1460 priv->has_stock_split =
false;
1461 priv->sort_dirty = FALSE;
1462 priv->splits.~SplitsVec();
1463 priv->children.~AccountVec();
1464 g_hash_table_destroy (priv->splits_hash);
1467 g_object_unref(acc);
1477 g_return_if_fail(acc);
1489 PERR(
"commit error: %d", errcode);
1490 gnc_engine_signal_commit_error( errcode );
1498 priv = GET_PRIVATE(acc);
1501 xaccFreeAccount(acc);
1505 destroy_pending_splits_for_account(
QofInstance *ent, gpointer acc)
1507 Transaction *trans = (Transaction *) ent;
1511 while ((split = xaccTransFindSplitByAccount(trans, static_cast<Account*>(acc))))
1521 g_return_if_fail(acc);
1526 priv = GET_PRIVATE(acc);
1531 qof_instance_increase_editlevel(acc);
1534 xaccFreeAccountChildren(acc);
1536 PINFO (
"freeing splits for account %p (%s)",
1537 acc, priv->accountName ? priv->accountName :
"(null)");
1546 for_each(priv->splits.rbegin(), priv->splits.rend(), [](Split *s) {
1551 priv->splits.clear();
1552 g_hash_table_remove_all (priv->splits_hash);
1566 qof_collection_foreach(col, destroy_pending_splits_for_account, acc);
1569 for (
auto lp = priv->lots; lp; lp = lp->next)
1571 GNCLot *lot =
static_cast<GNCLot*
>(lp->data);
1572 gnc_lot_destroy (lot);
1575 g_list_free(priv->lots);
1576 priv->lots =
nullptr;
1578 qof_instance_set_dirty(&acc->inst);
1579 qof_instance_decrease_editlevel(acc);
1583 xaccAccountBringUpToDate(acc);
1592 g_return_if_fail(GNC_IS_ACCOUNT(acc));
1594 qof_instance_set_destroying(acc, TRUE);
1602 auto priv = GET_PRIVATE(acc);
1603 std::vector<Transaction*> transactions;
1604 transactions.reserve(priv->splits.size());
1605 std::transform(priv->splits.begin(), priv->splits.end(),
1606 back_inserter(transactions),
1607 [](
auto split) {
return split->parent; });
1608 std::stable_sort(transactions.begin(), transactions.end());
1609 transactions.erase(std::unique(transactions.begin(), transactions.end()),
1610 transactions.end());
1612 std::for_each(transactions.rbegin(), transactions.rend(),
1621 xaccAcctChildrenEqual(
const AccountVec& na,
1622 const AccountVec& nb,
1623 gboolean check_guids)
1625 if (na.size() != nb.size())
1627 PINFO (
"Accounts have different numbers of children");
1633 auto it_b = std::find_if (nb.begin(), nb.end(), [aa](
auto ab) ->
bool 1635 if (!aa)
return (!ab);
1636 if (!ab)
return false;
1637 auto code_a{GET_PRIVATE(aa)->accountCode};
1638 auto code_b{GET_PRIVATE(ab)->accountCode};
1639 if ((code_a && *code_a) || (code_b && *code_b))
return !g_strcmp0 (code_a, code_b);
1640 return !g_strcmp0 (GET_PRIVATE(aa)->accountName, GET_PRIVATE(ab)->accountName);
1643 if (it_b == nb.end())
1645 PINFO (
"Unable to find matching child account.");
1656 PWARN (
"accounts %s and %s differ", sa, sb);
1670 if (!aa && !ab)
return TRUE;
1672 g_return_val_if_fail(GNC_IS_ACCOUNT(aa), FALSE);
1673 g_return_val_if_fail(GNC_IS_ACCOUNT(ab), FALSE);
1675 priv_aa = GET_PRIVATE(aa);
1676 priv_ab = GET_PRIVATE(ab);
1677 if (priv_aa->type != priv_ab->type)
1679 PWARN (
"types differ: %d vs %d", priv_aa->type, priv_ab->type);
1683 if (g_strcmp0(priv_aa->accountName, priv_ab->accountName) != 0)
1685 PWARN (
"names differ: %s vs %s", priv_aa->accountName, priv_ab->accountName);
1689 if (g_strcmp0(priv_aa->accountCode, priv_ab->accountCode) != 0)
1691 PWARN (
"codes differ: %s vs %s", priv_aa->accountCode, priv_ab->accountCode);
1695 if (g_strcmp0(priv_aa->description, priv_ab->description) != 0)
1697 PWARN (
"descriptions differ: %s vs %s", priv_aa->description, priv_ab->description);
1703 PWARN (
"commodities differ");
1711 PWARN (
"GUIDs differ");
1716 if (qof_instance_compare_kvp (QOF_INSTANCE (aa), QOF_INSTANCE (ab)) != 0)
1721 frame_a = qof_instance_kvp_as_string (QOF_INSTANCE (aa));
1722 frame_b = qof_instance_kvp_as_string (QOF_INSTANCE (ab));
1724 PWARN (
"kvp frames differ:\n%s\n\nvs\n\n%s", frame_a, frame_b);
1740 PWARN (
"starting balances differ: %s vs %s", str_a, str_b);
1749 priv_ab->starting_noclosing_balance))
1757 PWARN (
"starting noclosing balances differ: %s vs %s", str_a, str_b);
1765 priv_ab->starting_cleared_balance))
1773 PWARN (
"starting cleared balances differ: %s vs %s", str_a, str_b);
1782 priv_ab->starting_reconciled_balance))
1790 PWARN (
"starting reconciled balances differ: %s vs %s", str_a, str_b);
1806 PWARN (
"balances differ: %s vs %s", str_a, str_b);
1822 PWARN (
"noclosing balances differ: %s vs %s", str_a, str_b);
1837 PWARN (
"cleared balances differ: %s vs %s", str_a, str_b);
1845 if (!
gnc_numeric_equal(priv_aa->reconciled_balance, priv_ab->reconciled_balance))
1853 PWARN (
"reconciled balances differ: %s vs %s", str_a, str_b);
1863 if (!std::equal (priv_aa->splits.begin(), priv_aa->splits.end(),
1864 priv_ab->splits.begin(), priv_ab->splits.end(),
1865 [check_guids](
auto sa,
auto sb)
1868 PWARN (
"splits differ");
1872 if (!xaccAcctChildrenEqual(priv_aa->children, priv_ab->children, check_guids))
1874 PWARN (
"children differ");
1888 g_return_if_fail(GNC_IS_ACCOUNT(acc));
1893 priv = GET_PRIVATE(acc);
1894 priv->sort_dirty = TRUE;
1902 g_return_if_fail(GNC_IS_ACCOUNT(acc));
1907 priv = GET_PRIVATE(acc);
1908 priv->balance_dirty = TRUE;
1915 g_return_if_fail (GNC_IS_ACCOUNT (acc));
1920 priv = GET_PRIVATE (acc);
1921 priv->defer_bal_computation = defer;
1929 priv = GET_PRIVATE (acc);
1930 return priv->defer_bal_computation;
1937 static bool split_cmp_less (
const Split* a,
const Split* b)
1947 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
1948 g_return_val_if_fail(GNC_IS_SPLIT(s), FALSE);
1950 priv = GET_PRIVATE(acc);
1951 if (!g_hash_table_add (priv->splits_hash, s))
1954 priv->splits.push_back (s);
1956 if (qof_instance_get_editlevel(acc) == 0)
1957 std::sort (priv->splits.begin(), priv->splits.end(), split_cmp_less);
1959 priv->sort_dirty =
true;
1966 priv->balance_dirty = TRUE;
1977 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
1978 g_return_val_if_fail(GNC_IS_SPLIT(s), FALSE);
1980 priv = GET_PRIVATE(acc);
1982 if (!g_hash_table_remove (priv->splits_hash, s))
1987 if (s == priv->splits.back())
1988 priv->splits.pop_back();
1990 priv->splits.erase (std::remove (priv->splits.begin(), priv->splits.end(), s),
1991 priv->splits.end());
1998 priv->balance_dirty = TRUE;
2008 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2010 priv = GET_PRIVATE(acc);
2011 if (!priv->sort_dirty || (!force && qof_instance_get_editlevel(acc) > 0))
2013 std::sort (priv->splits.begin(), priv->splits.end(), split_cmp_less);
2014 priv->sort_dirty = FALSE;
2015 priv->balance_dirty = TRUE;
2019 xaccAccountBringUpToDate(
Account *acc)
2035 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2036 g_return_if_fail(guid);
2039 PINFO(
"acct=%p", acc);
2041 qof_instance_set_guid (&acc->inst, guid);
2042 qof_instance_set_dirty(&acc->inst);
2053 if (!guid || !book)
return nullptr;
2066 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2068 priv = GET_PRIVATE(acc);
2077 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2088 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2090 priv = GET_PRIVATE(acc);
2092 std::for_each (priv->children.begin(), priv->children.end(),
2102 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
2104 return GET_PRIVATE(acc)->policy;
2112 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2114 priv = GET_PRIVATE(acc);
2122 xaccAccountRemoveLot (
Account *acc, GNCLot *lot)
2126 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2127 g_return_if_fail(GNC_IS_LOT(lot));
2129 priv = GET_PRIVATE(acc);
2130 g_return_if_fail(priv->lots);
2132 ENTER (
"(acc=%p, lot=%p)", acc, lot);
2133 priv->lots = g_list_remove(priv->lots, lot);
2134 qof_event_gen (QOF_INSTANCE(lot), QOF_EVENT_REMOVE,
nullptr);
2136 LEAVE (
"(acc=%p, lot=%p)", acc, lot);
2143 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2144 g_return_if_fail(GNC_IS_LOT(lot));
2151 ENTER (
"(acc=%p, lot=%p)", acc, lot);
2156 auto priv = GET_PRIVATE(lot_acc);
2157 priv->lots = g_list_remove(priv->lots, lot);
2161 auto priv = GET_PRIVATE(acc);
2162 priv->lots = g_list_prepend(priv->lots, lot);
2163 gnc_lot_set_account(lot, acc);
2173 LEAVE (
"(acc=%p, lot=%p)", acc, lot);
2179 xaccPreSplitMove (Split *split)
2185 xaccPostSplitMove (Split *split,
Account *accto)
2189 xaccSplitSetAccount(split, accto);
2201 g_return_if_fail(GNC_IS_ACCOUNT(accfrom));
2202 g_return_if_fail(GNC_IS_ACCOUNT(accto));
2205 from_priv = GET_PRIVATE(accfrom);
2206 if (from_priv->splits.empty() || accfrom == accto)
2211 ENTER (
"(accfrom=%p, accto=%p)", accfrom, accto);
2216 std::for_each (from_priv->splits.begin(), from_priv->splits.end(), xaccPreSplitMove);
2233 auto splits = from_priv->splits;
2234 std::for_each (splits.begin(), splits.end(), [accto](
auto s){ xaccPostSplitMove (s, accto); });
2237 g_assert(from_priv->splits.empty());
2238 g_assert(from_priv->lots ==
nullptr);
2242 LEAVE (
"(accfrom=%p, accto=%p)", accfrom, accto);
2277 if (
nullptr == acc)
return;
2279 auto priv = GET_PRIVATE(acc);
2280 if (qof_instance_get_editlevel(acc) > 0)
return;
2281 if (!priv->balance_dirty || priv->defer_bal_computation)
return;
2285 auto balance = priv->starting_balance;
2286 auto noclosing_balance = priv->starting_noclosing_balance;
2287 auto cleared_balance = priv->starting_cleared_balance;
2288 auto reconciled_balance = priv->starting_reconciled_balance;
2289 auto has_stock_split =
false;
2291 PINFO (
"acct=%s starting baln=%" G_GINT64_FORMAT
"/%" G_GINT64_FORMAT,
2292 priv->accountName, balance.num, balance.denom);
2293 for (
auto split : priv->splits)
2301 auto new_balance = gnc_numeric_add_fixed(balance, amt);
2307 for (
auto psplit : priv->splits)
2309 if (psplit == split)
2315 balance = new_balance;
2316 has_stock_split =
true;
2320 split->adjusted_amount = amt;
2321 balance = gnc_numeric_add_fixed(balance, amt);
2324 if (
NREC != split->reconciled)
2326 cleared_balance = gnc_numeric_add_fixed(cleared_balance, amt);
2329 if (
YREC == split->reconciled ||
2330 FREC == split->reconciled)
2332 reconciled_balance =
2333 gnc_numeric_add_fixed(reconciled_balance, amt);
2337 noclosing_balance = gnc_numeric_add_fixed(noclosing_balance, amt);
2339 split->balance = balance;
2340 split->noclosing_balance = noclosing_balance;
2341 split->cleared_balance = cleared_balance;
2342 split->reconciled_balance = reconciled_balance;
2346 priv->balance = balance;
2347 priv->noclosing_balance = noclosing_balance;
2348 priv->cleared_balance = cleared_balance;
2349 priv->reconciled_balance = reconciled_balance;
2350 priv->balance_dirty = FALSE;
2351 priv->has_stock_split = has_stock_split;
2370 -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
2378 const char *da, *db;
2381 if (aa == ab)
return 0;
2385 priv_aa = GET_PRIVATE(aa);
2386 priv_ab = GET_PRIVATE(ab);
2389 da = priv_aa->accountCode;
2390 db = priv_ab->accountCode;
2393 result = g_strcmp0 (da, db);
2399 if (-1 == revorder[0])
2404 revorder [typeorder[i]] = i;
2413 if (ta < tb)
return -1;
2414 if (ta > tb)
return +1;
2417 da = priv_aa->accountName;
2418 db = priv_ab->accountName;
2442 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2446 priv = GET_PRIVATE(acc);
2447 if (priv->type == tip)
2452 priv->balance_dirty = TRUE;
2463 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2464 g_return_if_fail(str);
2467 priv = GET_PRIVATE(acc);
2468 if (g_strcmp0(str, priv->accountName) == 0)
2483 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2486 priv = GET_PRIVATE(acc);
2487 if (g_strcmp0(str, priv->accountCode) == 0)
2502 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2505 priv = GET_PRIVATE(acc);
2506 if (g_strcmp0(str, priv->description) == 0)
2516 set_kvp_gnc_numeric_path (
Account *acc,
const std::vector<std::string>& path,
2517 std::optional<gnc_numeric> value)
2520 qof_instance_set_path_kvp<gnc_numeric> (QOF_INSTANCE(acc), value, path);
2524 static std::optional<gnc_numeric>
2525 get_kvp_gnc_numeric_path (
const Account *acc,
const Path& path)
2527 return qof_instance_get_path_kvp<gnc_numeric> (QOF_INSTANCE(acc), path);
2531 set_kvp_string_path (
Account *acc, std::vector<std::string>
const & path,
2534 std::optional<const char*> val;
2535 if (value && *value)
2536 val = g_strdup(value);
2539 qof_instance_set_path_kvp<const char*> (QOF_INSTANCE(acc), val, path);
2544 get_kvp_string_path (
const Account *acc,
const Path& path)
2546 auto rv{qof_instance_get_path_kvp<const char*> (QOF_INSTANCE(acc), path)};
2547 return rv ? *rv :
nullptr;
2551 set_kvp_account_path (
Account* acc,
const Path& path,
const Account* kvp_account)
2553 std::optional<GncGUID*> val;
2558 qof_instance_set_path_kvp<GncGUID*> (QOF_INSTANCE(acc), val, path);
2563 get_kvp_account_path (
const Account *acc,
const Path& path)
2565 auto val{qof_instance_get_path_kvp<GncGUID*> (QOF_INSTANCE(acc), path)};
2570 set_kvp_boolean_path (
Account *acc,
const Path& path, gboolean option)
2572 set_kvp_string_path (acc, path, option ?
"true" :
nullptr);
2576 get_kvp_boolean_path (
const Account *acc,
const Path& path)
2578 auto slot{QOF_INSTANCE(acc)->kvp_data->get_slot(path)};
2579 if (!slot)
return false;
2580 switch (slot->get_type())
2582 case KvpValueImpl::Type::INT64:
2583 return slot->get<int64_t>() != 0;
2584 case KvpValueImpl::Type::STRING:
2585 return g_strcmp0 (slot->get<
const char*>(),
"true") == 0;
2592 set_kvp_int64_path (
Account *acc,
const Path& path, std::optional<gint64> value)
2595 qof_instance_set_path_kvp<int64_t> (QOF_INSTANCE(acc), value, path);
2599 static const std::optional<gint64>
2600 get_kvp_int64_path (
const Account *acc,
const Path& path)
2602 return qof_instance_get_path_kvp<int64_t> (QOF_INSTANCE(acc), path);
2606 get_kvp_guid_path (
const Account *acc,
const Path& path)
2608 auto val{qof_instance_get_path_kvp<GncGUID*> (QOF_INSTANCE(acc), path)};
2615 set_kvp_string_path (acc, {
"color"}, str);
2621 set_kvp_string_path (acc, {
"filter"}, str);
2627 set_kvp_string_path (acc, {
"sort-order"}, str);
2633 set_kvp_boolean_path (acc, {
"sort-reversed"}, sortreversed);
2641 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2642 g_return_if_fail(GNC_IS_ACCOUNT(parent));
2644 parent_acc = GNC_ACCOUNT(parent);
2648 mark_account (parent_acc);
2657 set_kvp_string_path (acc, {
"notes"}, str);
2663 g_return_if_fail (GNC_IS_ACCOUNT(acc));
2664 set_kvp_string_path (acc, {KEY_ONLINE_ID}, id);
2671 g_return_if_fail (GNC_IS_ACCOUNT(acc));
2672 g_return_if_fail (tag && *tag);
2674 set_kvp_account_path (acc, {
"associated-account", tag}, assoc_acct);
2683 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2684 g_return_if_fail(GNC_IS_COMMODITY(com));
2687 priv = GET_PRIVATE(acc);
2688 if (com == priv->commodity)
2693 priv->commodity = com;
2696 priv->non_standard_scu = FALSE;
2699 for (
auto s : priv->splits)
2708 priv->sort_dirty = TRUE;
2709 priv->balance_dirty = TRUE;
2726 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2728 priv = GET_PRIVATE(acc);
2730 priv->commodity_scu = scu;
2732 priv->non_standard_scu = TRUE;
2740 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0);
2741 return GET_PRIVATE(acc)->commodity_scu;
2749 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0);
2751 priv = GET_PRIVATE(acc);
2752 if (priv->non_standard_scu || !priv->commodity)
2753 return priv->commodity_scu;
2762 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2764 priv = GET_PRIVATE(acc);
2765 if (priv->non_standard_scu == flag)
2768 priv->non_standard_scu = flag;
2776 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0);
2777 return GET_PRIVATE(acc)->non_standard_scu;
2787 if ((!acc) || (!currency))
return;
2790 set_kvp_string_path (acc, {
"old-currency"}, s);
2794 auto commodity = gnc_commodity_table_lookup_unique (
table, s);
2806 g_return_if_fail (GNC_IS_ACCOUNT(acc));
2811 auto children = GET_PRIVATE(acc)->children;
2812 for (
auto child : children)
2820 account_foreach_descendant_sorted (
const Account *acc, std::function<
void(
Account*)> account_cb)
2822 g_return_if_fail (GNC_IS_ACCOUNT(acc));
2824 auto children = GET_PRIVATE(acc)->children;
2825 std::sort (children.begin(), children.end(),
2828 for (
auto child : children)
2831 account_foreach_descendant_sorted (child, account_cb);
2843 g_assert(GNC_IS_ACCOUNT(new_parent));
2844 g_assert(GNC_IS_ACCOUNT(child));
2847 ppriv = GET_PRIVATE(new_parent);
2848 cpriv = GET_PRIVATE(child);
2849 old_parent = cpriv->parent;
2850 if (old_parent == new_parent)
2872 PWARN (
"reparenting accounts across books is not correctly supported\n");
2881 cpriv->parent = new_parent;
2882 ppriv->children.push_back (child);
2883 qof_instance_set_dirty(&new_parent->inst);
2884 qof_instance_set_dirty(&child->inst);
2907 if (!parent)
return;
2909 ppriv = GET_PRIVATE(parent);
2910 cpriv = GET_PRIVATE(child);
2912 if (cpriv->parent != parent)
2914 PERR (
"account not a child of parent");
2922 ppriv->children.erase (std::remove (ppriv->children.begin(), ppriv->children.end(), child),
2923 ppriv->children.end());
2929 cpriv->parent =
nullptr;
2937 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
2938 return GET_PRIVATE(acc)->parent;
2944 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
2955 g_return_val_if_fail(GNC_IS_ACCOUNT(account), FALSE);
2956 return (GET_PRIVATE(account)->parent ==
nullptr);
2962 g_return_val_if_fail(GNC_IS_ACCOUNT(account),
nullptr);
2963 auto& children = GET_PRIVATE(account)->children;
2964 return std::accumulate (children.rbegin(), children.rend(),
static_cast<GList*
>(
nullptr),
2971 g_return_val_if_fail(GNC_IS_ACCOUNT(account),
nullptr);
2978 g_return_val_if_fail(GNC_IS_ACCOUNT(account), 0);
2979 return GET_PRIVATE(account)->children.size();
2985 g_return_val_if_fail(GNC_IS_ACCOUNT(parent), -1);
2986 g_return_val_if_fail(GNC_IS_ACCOUNT(child), -1);
2987 auto& children = GET_PRIVATE(parent)->children;
2988 auto find_it = std::find (children.begin(), children.end(), child);
2989 return find_it == children.end() ? -1 : std::distance (children.begin(), find_it);
2995 g_return_val_if_fail(GNC_IS_ACCOUNT(parent),
nullptr);
2996 if ((
size_t)num >= GET_PRIVATE(parent)->children.size())
2998 return static_cast<Account*
>(GET_PRIVATE(parent)->children.at (num));
3015 g_return_val_if_fail(GNC_IS_ACCOUNT(account), 0);
3017 priv = GET_PRIVATE(account);
3020 account = priv->parent;
3021 priv = GET_PRIVATE(account);
3032 g_return_val_if_fail(GNC_IS_ACCOUNT(account), 0);
3034 priv = GET_PRIVATE(account);
3035 if (!priv->children.size())
3038 return 1 + std::accumulate (priv->children.begin(), priv->children.end(),
3039 0, [](
auto a,
auto b)
3046 GList* list =
nullptr;
3048 return g_list_reverse (list);
3054 GList* list =
nullptr;
3055 account_foreach_descendant_sorted (account, [&list](
auto a){ list = g_list_prepend (list, a); });
3056 return g_list_reverse (list);
3065 account_foreach_descendant_breadthfirst_until (
const Account *acc,
3069 g_return_val_if_fail (GNC_IS_ACCOUNT(acc),
nullptr);
3070 g_return_val_if_fail (thunk,
nullptr);
3072 auto& children{GET_PRIVATE(acc)->children};
3074 for (
auto acc : children)
3075 if (
auto result = thunk (acc, user_data))
3078 for (
auto acc: children)
3079 if (
auto result = account_foreach_descendant_breadthfirst_until (acc, thunk, user_data))
3086 is_acct_name (
Account *account, gpointer user_data)
3088 auto name {
static_cast<gchar*
>(user_data)};
3095 return (
Account*)account_foreach_descendant_breadthfirst_until (parent, is_acct_name, (
char*)name);
3099 is_acct_code (
Account *account, gpointer user_data)
3101 auto name {
static_cast<gchar*
>(user_data)};
3108 return (
Account*)account_foreach_descendant_breadthfirst_until (parent, is_acct_code, (
char*)code);
3112 is_opening_balance_account (
Account* account, gpointer data)
3114 gnc_commodity* commodity = GNC_COMMODITY(data);
3131 gnc_account_lookup_by_full_name_helper (
const Account *parent,
3134 g_return_val_if_fail(GNC_IS_ACCOUNT(parent),
nullptr);
3135 g_return_val_if_fail(names,
nullptr);
3138 for (
auto account : GET_PRIVATE(parent)->children)
3140 auto priv = GET_PRIVATE(account);
3141 if (g_strcmp0(priv->accountName, names[0]) == 0)
3145 if (names[1] ==
nullptr)
3149 if (priv->children.empty())
3153 if (
auto found = gnc_account_lookup_by_full_name_helper(account, &names[1]))
3171 g_return_val_if_fail(GNC_IS_ACCOUNT(any_acc),
nullptr);
3172 g_return_val_if_fail(name,
nullptr);
3175 rpriv = GET_PRIVATE(root);
3176 while (rpriv->parent)
3178 root = rpriv->parent;
3179 rpriv = GET_PRIVATE(root);
3182 found = gnc_account_lookup_by_full_name_helper(root, names);
3191 gnc_commodity* commodity)
3194 auto rpriv{GET_PRIVATE(root)};
3195 for (
auto account : rpriv->children)
3207 retval = g_list_prepend(retval, account);
3212 for (
auto account : rpriv->children)
3219 retval = g_list_concat(result, retval);
3229 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3230 g_return_if_fail(thunk);
3231 std::for_each (GET_PRIVATE(acc)->children.begin(), GET_PRIVATE(acc)->children.end(),
3232 [user_data, thunk](
auto a){ thunk (a, user_data); });
3248 gpointer result {
nullptr};
3250 g_return_val_if_fail (GNC_IS_ACCOUNT(acc),
nullptr);
3251 g_return_val_if_fail (thunk,
nullptr);
3253 for (
auto child : GET_PRIVATE(acc)->children)
3255 result = thunk (child, user_data);
3270 return GET_PRIVATE(acc)->type;
3274 qofAccountGetTypeString (
const Account *acc)
3276 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3281 qofAccountSetType (
Account *acc,
const char *type_string)
3283 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3284 g_return_if_fail(type_string);
3291 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3292 return GET_PRIVATE(acc)->accountName;
3295 std::vector<const Account*>
3296 gnc_account_get_all_parents (
const Account *account)
3298 std::vector<const Account*> rv;
3309 if (
nullptr == account)
3310 return g_strdup(
"");
3313 g_return_val_if_fail(GNC_IS_ACCOUNT(account), g_strdup(
""));
3315 auto path{gnc_account_get_all_parents (account)};
3316 auto seps_size{path.empty() ? 0 : strlen (account_separator) * (path.size() - 1)};
3317 auto alloc_size{std::accumulate (path.begin(), path.end(), seps_size,
3318 [](
auto sum,
auto acc)
3320 auto rv = g_new (
char, alloc_size + 1);
3323 std::for_each (path.rbegin(), path.rend(),
3327 p = stpcpy (p, account_separator);
3338 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3339 return GET_PRIVATE(acc)->accountCode;
3345 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3346 return GET_PRIVATE(acc)->description;
3352 return get_kvp_string_path (acc, {
"color"});
3358 return get_kvp_string_path (acc, {
"filter"});
3364 return get_kvp_string_path (acc, {
"sort-order"});
3370 return get_kvp_boolean_path (acc, {
"sort-reversed"});
3376 return get_kvp_string_path (acc, {
"notes"});
3382 g_return_val_if_fail (GNC_IS_ACCOUNT(acc),
nullptr);
3383 return get_kvp_string_path (acc, {KEY_ONLINE_ID});
3389 g_return_val_if_fail (tag && *tag,
nullptr);
3391 return get_kvp_account_path (acc, {
"associated-account", tag});
3398 if (
auto s = get_kvp_string_path (acc, {
"old-currency"}))
3401 return gnc_commodity_table_lookup_unique (
table, s);
3410 if (!GNC_IS_ACCOUNT(acc))
3412 return GET_PRIVATE(acc)->commodity;
3417 g_return_val_if_fail (GNC_IS_ACCOUNT (account),
nullptr);
3433 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3435 priv = GET_PRIVATE(acc);
3436 priv->starting_balance = start_baln;
3437 priv->balance_dirty = TRUE;
3442 const gnc_numeric start_baln)
3446 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3448 priv = GET_PRIVATE(acc);
3449 priv->starting_cleared_balance = start_baln;
3450 priv->balance_dirty = TRUE;
3455 const gnc_numeric start_baln)
3459 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3461 priv = GET_PRIVATE(acc);
3462 priv->starting_reconciled_balance = start_baln;
3463 priv->balance_dirty = TRUE;
3469 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3470 return GET_PRIVATE(acc)->balance;
3476 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3477 return GET_PRIVATE(acc)->cleared_balance;
3483 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3484 return GET_PRIVATE(acc)->reconciled_balance;
3488 xaccAccountGetProjectedMinimumBalance (
const Account *acc)
3491 std::optional<gnc_numeric> minimum;
3493 auto before_today_end = [&minimum, today](
const Split *s) ->
bool 3503 return minimum ? *minimum : gnc_numeric_zero();
3509 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
false);
3510 return GET_PRIVATE(acc)->has_stock_split;
3518 GetBalanceAsOfDate (
Account *acc,
time64 date, std::function<gnc_numeric(Split*)> split_to_numeric)
3520 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3525 auto is_before_date = [date](
auto s) ->
bool 3529 return latest_split ? split_to_numeric (latest_split) : gnc_numeric_zero();
3539 xaccAccountGetNoclosingBalanceAsOfDate (
Account *acc,
time64 date)
3554 xaccAccountGetPresentBalance (
const Account *acc)
3556 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3573 xaccAccountConvertBalanceToCurrency(
const Account *acc,
3574 gnc_numeric balance,
3575 const gnc_commodity *balance_currency,
3576 const gnc_commodity *new_currency)
3585 book = gnc_account_get_book (acc);
3589 pdb, balance, balance_currency, new_currency);
3599 xaccAccountConvertBalanceToCurrencyAsOfDate(
const Account *acc,
3600 gnc_numeric balance,
3601 const gnc_commodity *balance_currency,
3602 const gnc_commodity *new_currency,
3612 book = gnc_account_get_book (acc);
3616 pdb, balance, balance_currency, new_currency, date);
3627 xaccAccountGetXxxBalanceInCurrency (
const Account *acc,
3628 xaccGetBalanceFn fn,
3629 const gnc_commodity *report_currency)
3632 gnc_numeric balance;
3634 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3635 g_return_val_if_fail(fn, gnc_numeric_zero());
3636 g_return_val_if_fail(GNC_IS_COMMODITY(report_currency), gnc_numeric_zero());
3638 priv = GET_PRIVATE(acc);
3640 balance = xaccAccountConvertBalanceToCurrency(acc, balance,
3647 xaccAccountGetXxxBalanceAsOfDateInCurrency(
Account *acc,
time64 date,
3648 xaccGetBalanceAsOfDateFn fn,
3649 const gnc_commodity *report_commodity)
3653 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3654 g_return_val_if_fail(fn, gnc_numeric_zero());
3655 g_return_val_if_fail(GNC_IS_COMMODITY(report_commodity), gnc_numeric_zero());
3657 priv = GET_PRIVATE(acc);
3658 return xaccAccountConvertBalanceToCurrencyAsOfDate(
3659 acc, fn(acc, date), priv->commodity, report_commodity, date);
3667 const gnc_commodity *currency;
3668 gnc_numeric balance;
3669 xaccGetBalanceFn fn;
3670 xaccGetBalanceAsOfDateFn asOfDateFn;
3681 xaccAccountBalanceHelper (
Account *acc, gpointer data)
3684 gnc_numeric balance;
3686 if (!cb->fn || !cb->currency)
3688 balance = xaccAccountGetXxxBalanceInCurrency (acc, cb->fn, cb->currency);
3695 xaccAccountBalanceAsOfDateHelper (
Account *acc, gpointer data)
3698 gnc_numeric balance;
3700 g_return_if_fail (cb->asOfDateFn && cb->currency);
3702 balance = xaccAccountGetXxxBalanceAsOfDateInCurrency (
3703 acc, cb->date, cb->asOfDateFn, cb->currency);
3722 xaccAccountGetXxxBalanceInCurrencyRecursive (
const Account *acc,
3723 xaccGetBalanceFn fn,
3724 const gnc_commodity *report_commodity,
3725 gboolean include_children)
3727 gnc_numeric balance;
3729 if (!acc)
return gnc_numeric_zero ();
3730 if (!report_commodity)
3732 if (!report_commodity)
3733 return gnc_numeric_zero();
3735 balance = xaccAccountGetXxxBalanceInCurrency (acc, fn, report_commodity);
3739 if (include_children)
3746 cb.balance = balance;
3752 balance = cb.balance;
3759 xaccAccountGetXxxBalanceAsOfDateInCurrencyRecursive (
3761 const gnc_commodity *report_commodity, gboolean include_children)
3763 gnc_numeric balance;
3765 g_return_val_if_fail(acc, gnc_numeric_zero());
3766 if (!report_commodity)
3768 if (!report_commodity)
3769 return gnc_numeric_zero();
3771 balance = xaccAccountGetXxxBalanceAsOfDateInCurrency(
3772 acc, date, fn, report_commodity);
3776 if (include_children)
3783 cb.balance = balance;
3785 CurrencyBalance cb = { report_commodity, balance,
nullptr, fn, date };
3789 balance = cb.balance;
3796 xaccAccountGetBalanceInCurrency (
const Account *acc,
3797 const gnc_commodity *report_commodity,
3798 gboolean include_children)
3801 rc = xaccAccountGetXxxBalanceInCurrencyRecursive (
3803 PINFO(
" baln=%" G_GINT64_FORMAT
"/%" G_GINT64_FORMAT, rc.num, rc.denom);
3809 xaccAccountGetClearedBalanceInCurrency (
const Account *acc,
3810 const gnc_commodity *report_commodity,
3811 gboolean include_children)
3813 return xaccAccountGetXxxBalanceInCurrencyRecursive (
3819 xaccAccountGetReconciledBalanceInCurrency (
const Account *acc,
3820 const gnc_commodity *report_commodity,
3821 gboolean include_children)
3823 return xaccAccountGetXxxBalanceInCurrencyRecursive (
3829 xaccAccountGetPresentBalanceInCurrency (
const Account *acc,
3830 const gnc_commodity *report_commodity,
3831 gboolean include_children)
3833 return xaccAccountGetXxxBalanceAsOfDateInCurrencyRecursive (
3840 xaccAccountGetProjectedMinimumBalanceInCurrency (
3842 const gnc_commodity *report_commodity,
3843 gboolean include_children)
3845 return xaccAccountGetXxxBalanceInCurrencyRecursive (
3846 acc, xaccAccountGetProjectedMinimumBalance, report_commodity,
3853 gboolean include_children)
3855 return xaccAccountGetXxxBalanceAsOfDateInCurrencyRecursive (
3863 gboolean include_children)
3865 return xaccAccountGetXxxBalanceAsOfDateInCurrencyRecursive
3866 (acc, date, xaccAccountGetNoclosingBalanceAsOfDate,
3867 report_commodity, include_children);
3882 xaccAccountGetNoclosingBalanceChangeForPeriod (
Account *acc,
time64 t1,
3883 time64 t2, gboolean recurse)
3894 const gnc_commodity *currency;
3895 gnc_numeric balanceChange;
3901 xaccAccountBalanceChangeHelper (
Account *acc, gpointer data)
3909 gnc_numeric balanceChange_conv = xaccAccountConvertBalanceToCurrencyAsOfDate(acc, balanceChange,
xaccAccountGetCommodity(acc), cbdiff->currency, cbdiff->t2);
3910 cbdiff->balanceChange =
gnc_numeric_add (cbdiff->balanceChange, balanceChange_conv,
3916 xaccAccountGetNoclosingBalanceChangeInCurrencyForPeriod (
Account *acc,
time64 t1,
3917 time64 t2, gboolean recurse)
3932 balanceChange = cbdiff.balanceChange;
3934 return balanceChange;
3941 xaccAccountGetSplits (
const Account *account)
3943 static const SplitsVec empty;
3944 g_return_val_if_fail (GNC_IS_ACCOUNT(account), empty);
3945 return GET_PRIVATE(account)->splits;
3951 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3952 auto priv{GET_PRIVATE(acc)};
3953 return std::accumulate (priv->splits.rbegin(), priv->splits.rend(),
3954 static_cast<GList*
>(
nullptr), g_list_prepend);
3958 xaccAccountGetSplitsSize (
const Account *account)
3960 g_return_val_if_fail (GNC_IS_ACCOUNT(account), 0);
3961 return GNC_IS_ACCOUNT(account) ? GET_PRIVATE(account)->splits.size() : 0;
3965 gnc_account_and_descendants_empty (
Account *acc)
3967 g_return_val_if_fail (GNC_IS_ACCOUNT (acc), FALSE);
3968 auto priv = GET_PRIVATE (acc);
3969 if (!priv->splits.empty())
return FALSE;
3970 return std::all_of (priv->children.begin(), priv->children.end(),
3971 gnc_account_and_descendants_empty);
3977 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3978 return g_list_copy(GET_PRIVATE(acc)->lots);
3983 gboolean (*match_func)(GNCLot *lot,
3984 gpointer user_data),
3985 gpointer user_data, GCompareFunc sort_func)
3989 GList *retval =
nullptr;
3991 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3993 priv = GET_PRIVATE(acc);
3994 for (lot_list = priv->lots; lot_list; lot_list = lot_list->next)
3996 GNCLot *lot =
static_cast<GNCLot*
>(lot_list->data);
4002 if (match_func && !(match_func)(lot, user_data))
4006 retval = g_list_prepend (retval, lot);
4010 retval = g_list_sort (retval, sort_func);
4017 gpointer (*proc)(GNCLot *lot,
void *data),
void *data)
4019 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
4020 g_return_val_if_fail(proc,
nullptr);
4022 for (
auto node = GET_PRIVATE(acc)->lots; node; node = node->next)
4023 if (
auto result = proc(GNC_LOT(node->data), data))
4037 return get_kvp_boolean_path(acc, {
"tax-related"});
4043 set_kvp_boolean_path(acc, {
"tax-related"}, tax_related);
4049 return get_kvp_string_path (acc, {
"tax-US",
"code"});
4055 set_kvp_string_path (acc, {
"tax-US",
"code"}, code);
4061 return get_kvp_string_path (acc, {
"tax-US",
"payer-name-source"});
4067 set_kvp_string_path (acc, {
"tax-US",
"payer-name-source"}, source);
4073 auto copy_number = get_kvp_int64_path (acc, {
"tax-US",
"copy-number"});
4074 return (copy_number && (*copy_number != 0)) ? *copy_number : 1;
4080 if (copy_number != 0)
4081 set_kvp_int64_path (acc, {
"tax-US",
"copy-number"}, copy_number);
4084 set_kvp_int64_path (acc, {
"tax-US",
"copy-number"}, std::nullopt);
4094 return _(dflt_acct_debit_str);
4096 auto result = gnc_acct_debit_strs.find(acct_type);
4097 if (result != gnc_acct_debit_strs.end())
4098 return _(result->second);
4100 return _(dflt_acct_debit_str);
4106 return _(dflt_acct_credit_str);
4108 auto result = gnc_acct_credit_strs.find(acct_type);
4109 if (result != gnc_acct_credit_strs.end())
4110 return _(result->second);
4112 return _(dflt_acct_credit_str);
4121 return get_kvp_boolean_path(acc, {
"placeholder"});
4127 set_kvp_boolean_path(acc, {
"placeholder"}, val);
4133 return get_kvp_boolean_path(acc, {
"import-append-text"});
4139 set_kvp_boolean_path(acc, {
"import-append-text"}, val);
4145 g_return_val_if_fail (GNC_IS_ACCOUNT(acc),
false);
4149 return !g_strcmp0 (get_kvp_string_path (acc, {
"equity-type"}),
"opening-balance");
4155 g_return_if_fail (GNC_IS_ACCOUNT(acc));
4158 set_kvp_string_path(acc, {
"equity-type"}, val ?
"opening-balance" :
nullptr);
4164 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), PLACEHOLDER_NONE);
4168 ? PLACEHOLDER_CHILD : PLACEHOLDER_NONE;
4177 return get_kvp_boolean_path (acc, {KEY_RECONCILE_INFO,
"auto-interest-transfer"});
4183 set_kvp_boolean_path (acc, {KEY_RECONCILE_INFO,
"auto-interest-transfer"}, val);
4192 return get_kvp_boolean_path (acc, {
"hidden"});
4198 set_kvp_boolean_path (acc, {
"hidden"}, val);
4206 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4210 priv = GET_PRIVATE(acc);
4211 while ((acc = priv->parent) !=
nullptr)
4213 priv = GET_PRIVATE(acc);
4228 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4229 g_return_val_if_fail(GNC_IS_ACCOUNT(ancestor), FALSE);
4232 while (parent && parent != ancestor)
4233 parent = GET_PRIVATE(parent)->parent;
4235 return (parent == ancestor);
4244 #define GNC_RETURN_ENUM_AS_STRING(x) case (ACCT_TYPE_ ## x): return #x; 4251 GNC_RETURN_ENUM_AS_STRING(NONE);
4252 GNC_RETURN_ENUM_AS_STRING(BANK);
4253 GNC_RETURN_ENUM_AS_STRING(CASH);
4254 GNC_RETURN_ENUM_AS_STRING(CREDIT);
4255 GNC_RETURN_ENUM_AS_STRING(ASSET);
4256 GNC_RETURN_ENUM_AS_STRING(LIABILITY);
4257 GNC_RETURN_ENUM_AS_STRING(STOCK);
4258 GNC_RETURN_ENUM_AS_STRING(MUTUAL);
4259 GNC_RETURN_ENUM_AS_STRING(CURRENCY);
4260 GNC_RETURN_ENUM_AS_STRING(INCOME);
4261 GNC_RETURN_ENUM_AS_STRING(EXPENSE);
4262 GNC_RETURN_ENUM_AS_STRING(EQUITY);
4263 GNC_RETURN_ENUM_AS_STRING(RECEIVABLE);
4264 GNC_RETURN_ENUM_AS_STRING(PAYABLE);
4265 GNC_RETURN_ENUM_AS_STRING(ROOT);
4266 GNC_RETURN_ENUM_AS_STRING(TRADING);
4267 GNC_RETURN_ENUM_AS_STRING(CHECKING);
4268 GNC_RETURN_ENUM_AS_STRING(SAVINGS);
4269 GNC_RETURN_ENUM_AS_STRING(MONEYMRKT);
4270 GNC_RETURN_ENUM_AS_STRING(CREDITLINE);
4272 PERR (
"asked to translate unknown account type %d.\n", type);
4278 #undef GNC_RETURN_ENUM_AS_STRING 4280 #define GNC_RETURN_ON_MATCH(x) \ 4281 if(g_strcmp0(#x, (str)) == 0) { *type = ACCT_TYPE_ ## x; return(TRUE); } 4287 GNC_RETURN_ON_MATCH(NONE);
4288 GNC_RETURN_ON_MATCH(BANK);
4289 GNC_RETURN_ON_MATCH(CASH);
4290 GNC_RETURN_ON_MATCH(CREDIT);
4291 GNC_RETURN_ON_MATCH(ASSET);
4292 GNC_RETURN_ON_MATCH(LIABILITY);
4293 GNC_RETURN_ON_MATCH(STOCK);
4294 GNC_RETURN_ON_MATCH(MUTUAL);
4295 GNC_RETURN_ON_MATCH(CURRENCY);
4296 GNC_RETURN_ON_MATCH(INCOME);
4297 GNC_RETURN_ON_MATCH(EXPENSE);
4298 GNC_RETURN_ON_MATCH(EQUITY);
4299 GNC_RETURN_ON_MATCH(RECEIVABLE);
4300 GNC_RETURN_ON_MATCH(PAYABLE);
4301 GNC_RETURN_ON_MATCH(ROOT);
4302 GNC_RETURN_ON_MATCH(TRADING);
4303 GNC_RETURN_ON_MATCH(CHECKING);
4304 GNC_RETURN_ON_MATCH(SAVINGS);
4305 GNC_RETURN_ON_MATCH(MONEYMRKT);
4306 GNC_RETURN_ON_MATCH(CREDITLINE);
4308 PERR(
"asked to translate unknown account type string %s.\n",
4309 str ? str :
"(null)");
4314 #undef GNC_RETURN_ON_MATCH 4360 return _(account_type_name [type]);
4402 PERR(
"bad account type: %d", type);
4448 PERR(
"bad account type: %d", type);
4555 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4557 priv = GET_PRIVATE(acc);
4568 gboolean retval = FALSE;
4569 auto date = get_kvp_int64_path (acc, {KEY_RECONCILE_INFO,
"last-date"});
4586 set_kvp_int64_path (acc, {KEY_RECONCILE_INFO,
"last-date"}, last_date);
4594 int *months,
int *days)
4596 if (!acc)
return FALSE;
4597 auto m{get_kvp_int64_path (acc, {KEY_RECONCILE_INFO,
"last-interval",
"months"})};
4598 auto d{get_kvp_int64_path (acc, {KEY_RECONCILE_INFO,
"last-interval",
"days"})};
4616 set_kvp_int64_path (acc, {KEY_RECONCILE_INFO,
"last-interval",
"months"}, months);
4617 set_kvp_int64_path (acc, {KEY_RECONCILE_INFO,
"last-interval",
"days"}, days);
4626 if (
auto date = get_kvp_int64_path (acc, {KEY_RECONCILE_INFO, KEY_POSTPONE,
"date"}))
4629 *postpone_date = *date;
4641 set_kvp_int64_path (acc, {KEY_RECONCILE_INFO, KEY_POSTPONE,
"date"}, postpone_date);
4649 gnc_numeric *balance)
4651 if (
auto bal = get_kvp_gnc_numeric_path (acc, {KEY_RECONCILE_INFO, KEY_POSTPONE,
"balance"}))
4666 set_kvp_gnc_numeric_path (acc, {KEY_RECONCILE_INFO, KEY_POSTPONE,
"balance"}, balance);
4676 set_kvp_gnc_numeric_path (acc, {KEY_RECONCILE_INFO, KEY_POSTPONE}, {});
4685 return get_kvp_string_path (acc, {
"last-num"});
4694 set_kvp_string_path (acc, {
"last-num"}, num);
4702 get_balance_limit (
const Account* acc,
const std::string& key, gnc_numeric* balance)
4704 auto limit = get_kvp_gnc_numeric_path (acc, {KEY_BALANCE_LIMIT, key});
4706 *balance = gnc_numeric_create (limit->num, limit->denom);
4707 return limit.has_value();
4711 set_balance_limit (
Account *acc,
const std::string& key, std::optional<gnc_numeric> balance)
4715 set_kvp_gnc_numeric_path (acc, {KEY_BALANCE_LIMIT, key}, balance);
4720 gnc_numeric *balance)
4722 return get_balance_limit (acc, KEY_BALANCE_HIGHER_LIMIT_VALUE, balance);
4727 gnc_numeric *balance)
4729 return get_balance_limit (acc, KEY_BALANCE_LOWER_LIMIT_VALUE, balance);
4735 set_balance_limit (acc, KEY_BALANCE_HIGHER_LIMIT_VALUE, balance);
4741 set_balance_limit (acc, KEY_BALANCE_LOWER_LIMIT_VALUE, balance);
4747 set_balance_limit (acc, KEY_BALANCE_HIGHER_LIMIT_VALUE, {});
4753 set_balance_limit (acc, KEY_BALANCE_LOWER_LIMIT_VALUE, {});
4759 return get_kvp_boolean_path (acc, {KEY_BALANCE_LIMIT, KEY_BALANCE_INCLUDE_SUB_ACCTS});
4765 set_kvp_boolean_path (acc, {KEY_BALANCE_LIMIT, KEY_BALANCE_INCLUDE_SUB_ACCTS}, inc_sub);
4772 GetOrMakeOrphanAccount (
Account *root, gnc_commodity * currency)
4777 g_return_val_if_fail (root,
nullptr);
4782 PERR (
"No currency specified!");
4786 accname = g_strconcat (_(
"Orphaned Gains"),
"-",
4802 _(
"Realized Gains or Losses from " 4803 "Commodity or Trading Accounts " 4804 "that haven't been recorded elsewhere."));
4820 auto gains_account = get_kvp_account_path (acc, path);
4822 if (gains_account ==
nullptr)
4825 set_kvp_account_path (acc, path, gains_account);
4828 return gains_account;
4840 set_kvp_string_path (acc, {
"old-price-source"}, src);
4849 if (!acc)
return nullptr;
4853 return get_kvp_string_path (acc, {
"old-price-source"});
4864 set_kvp_string_path (acc, {
"old-quote-tz"}, tz);
4873 if (!acc)
return nullptr;
4875 return get_kvp_string_path (acc, {
"old-quote-tz"});
4888 set_kvp_int64_path (acc, {KEY_RECONCILE_INFO, KEY_INCLUDE_CHILDREN}, status);
4901 return get_kvp_boolean_path (acc, {KEY_RECONCILE_INFO, KEY_INCLUDE_CHILDREN});
4910 auto has_description = [description](
const Split* s) ->
bool 4935 g_return_if_fail(GNC_IS_ACCOUNT(to_parent));
4936 g_return_if_fail(GNC_IS_ACCOUNT(from_parent));
4939 auto from_priv = GET_PRIVATE(from_parent);
4940 if (from_priv->children.empty())
4944 auto children = from_priv->children;
4945 for (
auto child : children)
4955 g_return_if_fail(GNC_IS_ACCOUNT(parent));
4957 auto ppriv = GET_PRIVATE(parent);
4958 for (
auto it_a = ppriv->children.begin(); it_a != ppriv->children.end(); it_a++)
4961 auto priv_a = GET_PRIVATE(acc_a);
4962 for (
auto it_b = std::next(it_a); it_b != ppriv->children.end(); it_b++)
4965 auto priv_b = GET_PRIVATE(acc_b);
4966 if (0 !=
null_strcmp(priv_a->accountName, priv_b->accountName))
4968 if (0 !=
null_strcmp(priv_a->accountCode, priv_b->accountCode))
4970 if (0 !=
null_strcmp(priv_a->description, priv_b->description))
4980 if (priv_a->type != priv_b->type)
4984 if (!priv_b->children.empty())
4986 auto work = priv_b->children;
4998 while (!priv_b->splits.empty())
4999 xaccSplitSetAccount (priv_b->splits.front(), acc_a);
5018 xaccSplitsBeginStagedTransactionTraversals (SplitsVec& splits)
5020 for (
auto s : splits)
5022 Transaction *trans = s->parent;
5035 xaccSplitsBeginStagedTransactionTraversals(GET_PRIVATE (account)->splits);
5041 if (trans ==
nullptr)
return FALSE;
5043 if (trans->marker < stage)
5045 trans->marker = stage;
5056 auto do_one_account = [](
auto acc)
5057 { gnc_account_foreach_split (acc, [](
auto s){ s->parent->marker = 0; }); };
5064 TransactionCallback thunk,
5070 auto splits = GET_PRIVATE(acc)->splits;
5071 for (
auto s : splits)
5073 auto trans = s->parent;
5074 if (trans && (trans->marker < stage))
5076 trans->marker = stage;
5079 auto retval = thunk(trans, cb_data);
5080 if (retval)
return retval;
5091 TransactionCallback thunk,
5101 priv = GET_PRIVATE(acc);
5102 for (
auto acc_p : priv->children)
5105 if (retval)
return retval;
5109 for (
auto s : priv->splits)
5112 if (trans && (trans->marker < stage))
5114 trans->marker = stage;
5117 retval = thunk(trans, cb_data);
5118 if (retval)
return retval;
5129 g_return_val_if_fail (GNC_IS_ACCOUNT(account), INT64_MAX);
5130 const auto& splits = xaccAccountGetSplits (account);
5139 int (*proc)(Transaction *t,
void *data),
5142 if (!acc || !proc)
return 0;
5153 if (!acc || !proc)
return 0;
5164 #define IMAP_FRAME "import-map" 5165 #define IMAP_FRAME_BAYES "import-map-bayes" 5169 gnc_account_imap_find_account (
Account *acc,
5170 const char *category,
5173 if (!acc || !key)
return nullptr;
5174 std::vector<std::string> path {IMAP_FRAME};
5176 path.push_back (category);
5177 path.push_back (key);
5178 return get_kvp_account_path (acc, path);
5182 gnc_account_imap_find_any (
QofBook *book,
const char* category,
const char *key)
5187 auto root = gnc_book_get_root_account (book);
5191 for (
auto ptr = accts; ptr; ptr = g_list_next (ptr))
5193 auto tmp_acc =
static_cast<Account*
> (ptr->data);
5195 if (gnc_account_imap_find_account (tmp_acc, category, key))
5201 g_list_free (accts);
5208 gnc_account_imap_add_account (
Account *acc,
5209 const char *category,
5213 if (!acc || !key || !added_acc || !*key)
return;
5215 auto path = category ? Path{IMAP_FRAME, category, key} : Path{IMAP_FRAME, key};
5217 set_kvp_account_path (acc, path, added_acc);
5222 gnc_account_imap_delete_account (
Account *acc,
5223 const char *category,
5226 if (!acc || !key)
return;
5228 auto path = category ? Path{IMAP_FRAME, category, key} : Path{IMAP_FRAME, key};
5229 if (qof_instance_has_path_slot (QOF_INSTANCE (acc), path))
5231 qof_instance_slot_path_delete (QOF_INSTANCE (acc), path);
5233 qof_instance_slot_path_delete_if_empty (QOF_INSTANCE (acc), {IMAP_FRAME, category});
5234 qof_instance_slot_path_delete_if_empty (QOF_INSTANCE (acc), {IMAP_FRAME});
5236 qof_instance_set_dirty (QOF_INSTANCE (acc));
5251 double product_difference;
5256 std::string account_guid;
5257 int64_t token_count;
5265 std::vector<AccountTokenCount> accounts;
5266 int64_t total_count;
5274 std::string account_guid;
5275 int32_t probability;
5279 build_token_info(
char const * suffix, KvpValue * value,
TokenAccountsInfo & tokenInfo)
5283 tokenInfo.total_count += value->get<int64_t>();
5285 tokenInfo.accounts.emplace_back(
AccountTokenCount{std::string{suffix}, value->get<int64_t>()});
5292 static constexpr
int probability_factor = 100000;
5294 static FinalProbabilityVec
5295 build_probabilities(ProbabilityVec
const & first_pass)
5297 FinalProbabilityVec ret;
5298 for (
auto const & first_pass_prob : first_pass)
5300 auto const & account_probability = first_pass_prob.second;
5305 int32_t probability = (account_probability.product /
5306 (account_probability.product + account_probability.product_difference)) * probability_factor;
5307 ret.push_back({first_pass_prob.first, probability});
5313 highest_probability(FinalProbabilityVec
const & probabilities)
5315 AccountInfo ret {
"", std::numeric_limits<int32_t>::min()};
5316 for (
auto const & prob : probabilities)
5317 if (prob.second > ret.probability)
5322 static ProbabilityVec
5323 get_first_pass_probabilities(
Account* acc, GList * tokens)
5328 for (
auto current_token = tokens; current_token; current_token = current_token->next)
5331 auto path = std::string{IMAP_FRAME_BAYES
"/"} + static_cast <
char const *> (current_token->data) +
"/";
5332 qof_instance_foreach_slot_prefix (QOF_INSTANCE (acc), path, &build_token_info, tokenInfo);
5333 for (
auto const & current_account_token : tokenInfo.accounts)
5335 auto item = std::find_if(ret.begin(), ret.end(), [¤t_account_token]
5336 (std::pair<std::string, AccountProbability>
const & a) {
5337 return current_account_token.account_guid == a.first;
5339 if (item != ret.end())
5341 item->second.product = ((double)current_account_token.token_count /
5342 (
double)tokenInfo.total_count) * item->second.product;
5343 item->second.product_difference = ((
double)1 - ((double)current_account_token.token_count /
5344 (
double)tokenInfo.total_count)) * item->second.product_difference;
5350 new_probability.product = ((double)current_account_token.token_count /
5351 (
double)tokenInfo.total_count);
5352 new_probability.product_difference = 1 - (new_probability.product);
5353 ret.push_back({current_account_token.account_guid, std::move(new_probability)});
5361 look_for_old_separator_descendants (
Account *root, std::string
const & full_name,
const gchar *separator)
5363 GList *top_accounts, *ptr;
5367 PINFO(
"Incoming full_name is '%s', current separator is '%s'", full_name.c_str (), separator);
5369 for (ptr = top_accounts; ptr; ptr = g_list_next (ptr))
5373 if (g_str_has_prefix (full_name.c_str (), name))
5375 gint name_len = strlen (name);
5376 const gchar old_sep = full_name[name_len];
5377 if (!g_ascii_isalnum (old_sep))
5379 if (name_len > found_len)
5381 found_sep = full_name[name_len];
5382 found_len = name_len;
5387 g_list_free (top_accounts);
5388 std::string new_name {full_name};
5390 std::replace (new_name.begin (), new_name.end (), found_sep, *separator);
5391 PINFO (
"Return full_name is '%s'", new_name.c_str ());
5396 get_guid_from_account_name (
Account * root, std::string
const & name)
5401 auto temp_account_name = look_for_old_separator_descendants (root, name,
5406 return temp_guid.to_string ();
5410 convert_entry (KvpEntry entry,
Account* root)
5413 auto account_name = entry.first.back();
5414 if (!gnc::GUID::is_valid_guid (account_name))
5420 entry.first.pop_back();
5421 auto guid_str = get_guid_from_account_name (root, account_name);
5422 entry.first.emplace_back (guid_str);
5424 std::string new_key {std::accumulate (entry.first.begin(), entry.first.end(), std::string {})};
5425 new_key = IMAP_FRAME_BAYES + new_key;
5426 return {new_key, entry.second};
5429 static std::vector<FlatKvpEntry>
5432 auto frame = qof_instance_get_slots (QOF_INSTANCE (acc));
5433 auto slot = frame->get_slot ({IMAP_FRAME_BAYES});
5436 auto imap_frame = slot->get<KvpFrame*> ();
5437 auto flat_kvp = imap_frame->flatten_kvp ();
5439 std::vector <FlatKvpEntry> ret;
5440 for (
auto const & flat_entry : flat_kvp)
5442 auto converted_entry = convert_entry (flat_entry, root);
5444 if (converted_entry.first.size())
5445 ret.emplace_back (converted_entry);
5451 convert_imap_account_bayes_to_flat (
Account *acc)
5453 auto frame = qof_instance_get_slots (QOF_INSTANCE (acc));
5454 if (!frame->get_keys().size())
5456 auto flat_imap = get_flat_imap(acc);
5457 if (!flat_imap.size ())
5460 frame->set({IMAP_FRAME_BAYES},
nullptr);
5461 std::for_each(flat_imap.begin(), flat_imap.end(),
5462 [&frame] (FlatKvpEntry
const & entry) {
5463 frame->set({entry.first.c_str()}, entry.second);
5465 qof_instance_set_dirty (QOF_INSTANCE (acc));
5474 imap_convert_bayes_to_flat (
QofBook * book)
5476 auto root = gnc_book_get_root_account (book);
5479 for (
auto ptr = accts; ptr; ptr = g_list_next (ptr))
5482 if (convert_imap_account_bayes_to_flat (acc))
5488 g_list_free (accts);
5495 imap_convert_bayes_to_flat_run =
false;
5510 check_import_map_data (
QofBook *book)
5512 if (gnc_features_check_used (book, GNC_FEATURE_GUID_FLAT_BAYESIAN) ||
5513 imap_convert_bayes_to_flat_run)
5517 imap_convert_bayes_to_flat (book);
5518 imap_convert_bayes_to_flat_run =
true;
5521 static constexpr
double threshold = .90 * probability_factor;
5529 auto book = gnc_account_get_book(acc);
5530 check_import_map_data (book);
5531 auto first_pass = get_first_pass_probabilities(acc, tokens);
5532 if (!first_pass.size())
5534 auto final_probabilities = build_probabilities(first_pass);
5535 if (!final_probabilities.size())
5537 auto best = highest_probability(final_probabilities);
5538 if (best.account_guid ==
"")
5540 if (best.probability < threshold)
5544 guid = gnc::GUID::from_string(best.account_guid);
5553 change_imap_entry (
Account *acc, std::string
const & path, int64_t token_count)
5555 PINFO(
"Source Account is '%s', Count is '%" G_GINT64_FORMAT
"'",
5559 if (
auto existing_token_count = get_kvp_int64_path (acc, {path}))
5561 PINFO(
"found existing value of '%" G_GINT64_FORMAT
"'", *existing_token_count);
5562 token_count += *existing_token_count;
5566 set_kvp_int64_path (acc, {path}, token_count);
5575 GList *current_token;
5577 char *account_fullname;
5586 check_import_map_data (gnc_account_get_book(acc));
5588 g_return_if_fail (added_acc !=
nullptr);
5592 PINFO(
"account name: '%s'", account_fullname);
5597 for (current_token = g_list_first(tokens); current_token;
5598 current_token = current_token->next)
5600 char* token =
static_cast<char*
>(current_token->data);
5605 if (!token || !token[0])
5609 PINFO(
"adding token '%s'", token);
5610 auto path = std::string {IMAP_FRAME_BAYES} +
'/' + token +
'/' + guid_string;
5612 change_imap_entry (acc, path, token_count);
5617 g_free (account_fullname);
5618 g_free (guid_string);
5625 build_non_bayes (
const char *key,
const GValue *value, gpointer user_data)
5627 if (!G_VALUE_HOLDS_BOXED (value))
5631 gchar *guid_string =
nullptr;
5636 guid = (
GncGUID*)g_value_get_boxed (value);
5639 PINFO(
"build_non_bayes: match string '%s', match account guid: '%s'",
5640 (
char*)key, guid_string);
5644 imapInfo_node->source_account = imapInfo->source_account;
5646 imapInfo_node->head = g_strdup (imapInfo->head);
5647 imapInfo_node->match_string = g_strdup (key);
5648 imapInfo_node->category = g_strdup (imapInfo->category);
5649 imapInfo_node->count = g_strdup (
" ");
5651 imapInfo->list = g_list_prepend (imapInfo->list, imapInfo_node);
5653 g_free (guid_string);
5657 build_bayes (
const char *suffix, KvpValue * value,
GncImapInfo & imapInfo)
5660 std::string account_guid {&suffix[guid_start]};
5664 guid = gnc::GUID::from_string (account_guid);
5668 PWARN(
"Invalid GUID string from %s%s", IMAP_FRAME_BAYES, suffix);
5670 auto map_account =
xaccAccountLookup (&guid, gnc_account_get_book (imapInfo.source_account));
5672 auto count = value->get <int64_t> ();
5673 imap_node->source_account = imapInfo.source_account;
5674 imap_node->map_account = map_account;
5675 imap_node->head = g_strdup_printf (
"%s%s", IMAP_FRAME_BAYES, suffix);
5676 imap_node->match_string = g_strndup (&suffix[1], guid_start - 2);
5677 imap_node->category = g_strdup(
" ");
5678 imap_node->count = g_strdup_printf (
"%" G_GINT64_FORMAT, count);
5679 imapInfo.list = g_list_prepend (imapInfo.list, imap_node);
5684 g_free (imapInfo->head);
5685 g_free (imapInfo->category);
5686 g_free (imapInfo->match_string);
5687 g_free (imapInfo->count);
5694 check_import_map_data (gnc_account_get_book (acc));
5698 qof_instance_foreach_slot_prefix (QOF_INSTANCE (acc), IMAP_FRAME_BAYES, &build_bayes, imapInfo);
5699 return g_list_reverse(imapInfo.list);
5705 GList *list =
nullptr;
5709 std::vector<std::string> path {IMAP_FRAME};
5711 path.emplace_back (category);
5713 imapInfo.source_account = acc;
5714 imapInfo.list = list;
5716 imapInfo.head = g_strdup (IMAP_FRAME);
5717 imapInfo.category = g_strdup (category);
5719 if (qof_instance_has_path_slot (QOF_INSTANCE (acc), path))
5721 qof_instance_foreach_slot (QOF_INSTANCE(acc), IMAP_FRAME, category,
5722 build_non_bayes, &imapInfo);
5724 g_free (imapInfo.head);
5725 g_free (imapInfo.category);
5726 return g_list_reverse(imapInfo.list);
5734 return g_strdup (category ?
5735 get_kvp_string_path (acc, {head, category}) :
5736 get_kvp_string_path (acc, {head}));
5743 get_kvp_guid_path (acc, {head, category}) :
5744 get_kvp_guid_path (acc, {head});
5749 char *match_string, gboolean empty)
5753 std::vector<std::string> path {head};
5755 path.emplace_back (category);
5757 path.emplace_back (match_string);
5759 if (qof_instance_has_path_slot (QOF_INSTANCE (acc), path))
5763 qof_instance_slot_path_delete_if_empty (QOF_INSTANCE(acc), path);
5765 qof_instance_slot_path_delete (QOF_INSTANCE(acc), path);
5766 PINFO(
"Account is '%s', head is '%s', category is '%s', match_string is'%s'",
5768 qof_instance_set_dirty (QOF_INSTANCE(acc));
5779 auto slots = qof_instance_get_slots_prefix (QOF_INSTANCE (acc), IMAP_FRAME_BAYES);
5780 if (!slots.size())
return;
5782 for (
auto const & entry : slots)
5784 qof_instance_slot_path_delete (QOF_INSTANCE (acc), {entry.first});
5786 qof_instance_set_dirty (QOF_INSTANCE(acc));
5795 destroy_all_child_accounts (
Account *acc, gpointer data)
5802 gnc_account_book_end(
QofBook* book)
5804 Account *root_account = gnc_book_get_root_account (book);
5814 accounts = g_list_reverse (accounts);
5815 g_list_foreach (accounts, (GFunc)destroy_all_child_accounts,
nullptr);
5816 g_list_free (accounts);
5829 static QofObject account_object_def =
5832 DI(.e_type = ) GNC_ID_ACCOUNT,
5835 DI(.book_begin = )
nullptr,
5836 DI(.book_end = ) gnc_account_book_end,
5839 DI(.foreach = ) qof_collection_foreach,
5844 gboolean xaccAccountRegister (
void)
5846 static QofParam params[] =
5849 ACCOUNT_NAME_, QOF_TYPE_STRING,
5854 ACCOUNT_CODE_, QOF_TYPE_STRING,
5859 ACCOUNT_DESCRIPTION_, QOF_TYPE_STRING,
5864 ACCOUNT_COLOR_, QOF_TYPE_STRING,
5869 ACCOUNT_FILTER_, QOF_TYPE_STRING,
5874 ACCOUNT_SORT_ORDER_, QOF_TYPE_STRING,
5879 ACCOUNT_SORT_REVERSED_, QOF_TYPE_BOOLEAN,
5884 ACCOUNT_NOTES_, QOF_TYPE_STRING,
5889 ACCOUNT_PRESENT_, QOF_TYPE_NUMERIC,
5893 ACCOUNT_BALANCE_, QOF_TYPE_NUMERIC,
5897 ACCOUNT_CLEARED_, QOF_TYPE_NUMERIC,
5901 ACCOUNT_RECONCILED_, QOF_TYPE_NUMERIC,
5905 ACCOUNT_TYPE_, QOF_TYPE_STRING,
5910 ACCOUNT_FUTURE_MINIMUM_, QOF_TYPE_NUMERIC,
5911 (
QofAccessFunc) xaccAccountGetProjectedMinimumBalance,
nullptr 5914 ACCOUNT_TAX_RELATED, QOF_TYPE_BOOLEAN,
5919 ACCOUNT_OPENING_BALANCE_, QOF_TYPE_BOOLEAN,
5924 ACCOUNT_SCU, QOF_TYPE_INT32,
5929 ACCOUNT_NSCU, QOF_TYPE_BOOLEAN,
5934 ACCOUNT_PARENT, GNC_ID_ACCOUNT,
5943 QOF_PARAM_GUID, QOF_TYPE_GUID,
5958 utest_account_get_private (
Account *acc)
5960 return GET_PRIVATE (acc);
5964 _utest_account_fill_functions(
void)
5968 func->get_private = utest_account_get_private;
5969 func->coll_get_root_account = gnc_coll_get_root_account;
5970 func->xaccFreeAccountChildren = xaccFreeAccountChildren;
5971 func->xaccFreeAccount = xaccFreeAccount;
5972 func->qofAccountSetParent = qofAccountSetParent;
5973 func->gnc_account_lookup_by_full_name_helper =
5974 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.
void xaccSplitSetAdjustedAmount(Split *s, gnc_numeric amt)
Sets the stock split adjusted amount of a split.
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.
const char * xaccAccountGetOnlineID(const Account *acc)
Get the account's online_id (see xaccAccountSetOnlineID).
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 xaccAccountSetOnlineID(Account *acc, const char *id)
Set the account's online_id, the identifier (e.g.
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.
gboolean xaccAccountHasStockSplit(const Account *acc)
Returns true if the account has a stock split, otherwise false.
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.
Reduce the result value by common factor elimination, using the smallest possible value for the denom...
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.
gnc_numeric gnc_numeric_mul(gnc_numeric a, gnc_numeric b, gint64 denom, gint how)
Multiply a times b, returning the product.
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 xaccSplitIsStockSplit(Split *s)
Returns true if the split is of type stock split.
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.
gnc_numeric gnc_numeric_div(gnc_numeric x, gnc_numeric y, gint64 denom, gint how)
Division.
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.
gnc_numeric xaccSplitGetAdjustedAmount(const Split *s)
Returns the stock-split adjusted amount of the split in the account's commodity.
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...