31 #include <glib/gi18n.h> 40 #include "TransactionP.hpp" 46 #include "qofinstance-p.h" 53 #include <unordered_set> 56 static QofLogModule log_module = GNC_MOD_ACCOUNT;
59 static gchar account_separator[8] =
".";
60 static gunichar account_uc_separator =
':';
62 static bool imap_convert_bayes_to_flat_run =
false;
65 static const std::string KEY_ASSOC_INCOME_ACCOUNT(
"ofx/associated-income-account");
66 static const std::string KEY_RECONCILE_INFO(
"reconcile-info");
67 static const std::string KEY_INCLUDE_CHILDREN(
"include-children");
68 static const std::string KEY_POSTPONE(
"postpone");
69 static const std::string KEY_LOT_MGMT(
"lot-mgmt");
70 static const std::string KEY_ONLINE_ID(
"online_id");
71 static const std::string KEY_IMP_APPEND_TEXT(
"import-append-text");
72 static const std::string AB_KEY(
"hbci");
73 static const std::string AB_ACCOUNT_ID(
"account-id");
74 static const std::string AB_ACCOUNT_UID(
"account-uid");
75 static const std::string AB_BANK_CODE(
"bank-code");
76 static const std::string AB_TRANS_RETRIEVAL(
"trans-retrieval");
78 static const std::string KEY_BALANCE_LIMIT(
"balance-limit");
79 static const std::string KEY_BALANCE_HIGHER_LIMIT_VALUE(
"higher-value");
80 static const std::string KEY_BALANCE_LOWER_LIMIT_VALUE(
"lower-value");
81 static const std::string KEY_BALANCE_INCLUDE_SUB_ACCTS(
"inlude-sub-accts");
83 using FinalProbabilityVec=std::vector<std::pair<std::string, int32_t>>;
84 using ProbabilityVec=std::vector<std::pair<std::string, struct AccountProbability>>;
85 using FlatKvpEntry=std::pair<std::string, KvpValue*>;
108 PROP_END_NOCLOSING_BALANCE,
109 PROP_END_CLEARED_BALANCE,
110 PROP_END_RECONCILED_BALANCE,
115 PROP_TAX_COPY_NUMBER,
126 PROP_IMP_APPEND_TEXT,
127 PROP_IS_OPENING_BALANCE,
128 PROP_OFX_INCOME_ACCOUNT,
132 PROP_AB_TRANS_RETRIEVAL,
140 PROP_START_NOCLOSING_BALANCE,
141 PROP_START_CLEARED_BALANCE,
142 PROP_START_RECONCILED_BALANCE,
145 #define GET_PRIVATE(o) \ 146 ((AccountPrivate*)gnc_account_get_instance_private((Account*)o)) 149 static const std::map<GNCAccountType, const char*> gnc_acct_debit_strs = {
166 static const char* dflt_acct_debit_str = N_(
"Debit");
169 static const std::map<GNCAccountType, const char*> gnc_acct_credit_strs = {
186 static const char* dflt_acct_credit_str = N_(
"Credit");
195 static void xaccAccountBringUpToDate (
Account *acc);
208 return account_separator;
212 gnc_get_account_separator (
void)
214 return account_uc_separator;
218 gnc_set_account_separator (
const gchar *separator)
223 uc = g_utf8_get_char_validated(separator, -1);
224 if ((uc == (gunichar) - 2) || (uc == (gunichar) - 1) || g_unichar_isalnum(uc))
226 account_uc_separator =
':';
227 strcpy(account_separator,
":");
231 account_uc_separator = uc;
232 count = g_unichar_to_utf8(uc, account_separator);
233 account_separator[count] =
'\0';
238 gchar *message =
nullptr;
240 if ( !invalid_account_names )
249 message = g_strdup_printf(
250 _(
"The separator character \"%s\" is used in one or more account names.\n\n" 251 "This will result in unexpected behaviour. " 252 "Either change the account names or choose another separator character.\n\n" 253 "Below you will find the list of invalid account names:\n" 254 "%s"), separator, account_list );
255 g_free ( account_list );
262 const gchar *separator;
266 check_acct_name (
Account *acct, gpointer user_data)
270 if (g_strstr_len (name, -1, cb->separator))
271 cb->list = g_list_prepend (cb->list, g_strdup (name));
276 g_return_val_if_fail (separator !=
nullptr,
nullptr);
277 if (!book)
return nullptr;
280 (AccountCb)check_acct_name, &cb);
287 static inline void mark_account (
Account *acc);
291 qof_instance_set_dirty(&acc->inst);
298 G_DEFINE_TYPE_WITH_PRIVATE(
Account, gnc_account, QOF_TYPE_INSTANCE)
305 priv = GET_PRIVATE(acc);
306 priv->parent =
nullptr;
317 priv->lots =
nullptr;
319 priv->commodity =
nullptr;
320 priv->commodity_scu = 0;
321 priv->non_standard_scu = FALSE;
323 priv->balance = gnc_numeric_zero();
324 priv->noclosing_balance = gnc_numeric_zero();
325 priv->cleared_balance = gnc_numeric_zero();
326 priv->reconciled_balance = gnc_numeric_zero();
327 priv->starting_balance = gnc_numeric_zero();
328 priv->starting_noclosing_balance = gnc_numeric_zero();
329 priv->starting_cleared_balance = gnc_numeric_zero();
330 priv->starting_reconciled_balance = gnc_numeric_zero();
331 priv->balance_dirty = FALSE;
332 priv->has_stock_split =
false;
334 new (&priv->children) AccountVec ();
335 new (&priv->splits) SplitsVec ();
336 priv->splits_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
337 priv->sort_dirty = FALSE;
341 gnc_account_dispose (GObject *acctp)
343 G_OBJECT_CLASS(gnc_account_parent_class)->dispose(acctp);
347 gnc_account_finalize(GObject* acctp)
349 G_OBJECT_CLASS(gnc_account_parent_class)->finalize(acctp);
359 gnc_account_get_property (GObject *
object,
367 g_return_if_fail(GNC_IS_ACCOUNT(
object));
369 account = GNC_ACCOUNT(
object);
370 priv = GET_PRIVATE(account);
374 g_value_set_string(value, priv->accountName);
380 g_value_set_string(value, priv->accountCode);
382 case PROP_DESCRIPTION:
383 g_value_set_string(value, priv->description);
393 g_value_set_int(value, priv->type);
396 g_value_take_object(value, priv->commodity);
398 case PROP_COMMODITY_SCU:
399 g_value_set_int(value, priv->commodity_scu);
401 case PROP_NON_STD_SCU:
402 g_value_set_boolean(value, priv->non_standard_scu);
404 case PROP_SORT_DIRTY:
405 g_value_set_boolean(value, priv->sort_dirty);
407 case PROP_BALANCE_DIRTY:
408 g_value_set_boolean(value, priv->balance_dirty);
410 case PROP_START_BALANCE:
411 g_value_set_boxed(value, &priv->starting_balance);
413 case PROP_START_NOCLOSING_BALANCE:
414 g_value_set_boxed(value, &priv->starting_noclosing_balance);
416 case PROP_START_CLEARED_BALANCE:
417 g_value_set_boxed(value, &priv->starting_cleared_balance);
419 case PROP_START_RECONCILED_BALANCE:
420 g_value_set_boxed(value, &priv->starting_reconciled_balance);
422 case PROP_END_BALANCE:
423 g_value_set_boxed(value, &priv->balance);
425 case PROP_END_NOCLOSING_BALANCE:
426 g_value_set_boxed(value, &priv->noclosing_balance);
428 case PROP_END_CLEARED_BALANCE:
429 g_value_set_boxed(value, &priv->cleared_balance);
431 case PROP_END_RECONCILED_BALANCE:
432 g_value_set_boxed(value, &priv->reconciled_balance);
436 g_value_set_pointer(value, priv->policy);
439 g_value_set_int(value, priv->mark);
441 case PROP_TAX_RELATED:
447 case PROP_TAX_SOURCE:
448 g_value_set_string(value,
451 case PROP_TAX_COPY_NUMBER:
452 g_value_set_int64(value,
458 case PROP_AUTO_INTEREST:
461 case PROP_IS_OPENING_BALANCE:
464 case PROP_PLACEHOLDER:
470 case PROP_SORT_ORDER:
473 case PROP_SORT_REVERSED:
476 case PROP_LOT_NEXT_ID:
478 g_value_set_int64 (value, 0);
479 qof_instance_get_path_kvp (QOF_INSTANCE (account), value, {KEY_LOT_MGMT,
"next-id"});
481 case PROP_ONLINE_ACCOUNT:
482 qof_instance_get_path_kvp (QOF_INSTANCE (account), value, {KEY_ONLINE_ID});
484 case PROP_IMP_APPEND_TEXT:
487 case PROP_OFX_INCOME_ACCOUNT:
488 qof_instance_get_path_kvp (QOF_INSTANCE (account), value, {KEY_ASSOC_INCOME_ACCOUNT});
490 case PROP_AB_ACCOUNT_ID:
491 qof_instance_get_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_ACCOUNT_ID});
493 case PROP_AB_ACCOUNT_UID:
494 qof_instance_get_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_ACCOUNT_UID});
496 case PROP_AB_BANK_CODE:
497 qof_instance_get_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_BANK_CODE});
499 case PROP_AB_TRANS_RETRIEVAL:
500 qof_instance_get_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_TRANS_RETRIEVAL});
503 G_OBJECT_WARN_INVALID_PROPERTY_ID(
object, prop_id, pspec);
509 gnc_account_set_property (GObject *
object,
516 g_return_if_fail(GNC_IS_ACCOUNT(
object));
517 account = GNC_ACCOUNT(
object);
518 if (prop_id < PROP_RUNTIME_0)
519 g_assert (qof_instance_get_editlevel(account));
529 case PROP_DESCRIPTION:
545 case PROP_COMMODITY_SCU:
548 case PROP_NON_STD_SCU:
551 case PROP_SORT_DIRTY:
554 case PROP_BALANCE_DIRTY:
557 case PROP_START_BALANCE:
558 number =
static_cast<gnc_numeric*
>(g_value_get_boxed(value));
561 case PROP_START_CLEARED_BALANCE:
562 number =
static_cast<gnc_numeric*
>(g_value_get_boxed(value));
565 case PROP_START_RECONCILED_BALANCE:
566 number =
static_cast<gnc_numeric*
>(g_value_get_boxed(value));
575 case PROP_TAX_RELATED:
581 case PROP_TAX_SOURCE:
583 g_value_get_string(value));
585 case PROP_TAX_COPY_NUMBER:
587 g_value_get_int64(value));
592 case PROP_AUTO_INTEREST:
595 case PROP_IS_OPENING_BALANCE:
598 case PROP_PLACEHOLDER:
604 case PROP_SORT_ORDER:
607 case PROP_SORT_REVERSED:
610 case PROP_LOT_NEXT_ID:
611 qof_instance_set_path_kvp (QOF_INSTANCE (account), value, {KEY_LOT_MGMT,
"next-id"});
613 case PROP_ONLINE_ACCOUNT:
614 qof_instance_set_path_kvp (QOF_INSTANCE (account), value, {KEY_ONLINE_ID});
616 case PROP_IMP_APPEND_TEXT:
619 case PROP_OFX_INCOME_ACCOUNT:
620 qof_instance_set_path_kvp (QOF_INSTANCE (account), value, {KEY_ASSOC_INCOME_ACCOUNT});
622 case PROP_AB_ACCOUNT_ID:
623 qof_instance_set_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_ACCOUNT_ID});
625 case PROP_AB_ACCOUNT_UID:
626 qof_instance_set_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_ACCOUNT_UID});
628 case PROP_AB_BANK_CODE:
629 qof_instance_set_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_BANK_CODE});
631 case PROP_AB_TRANS_RETRIEVAL:
632 qof_instance_set_path_kvp (QOF_INSTANCE (account), value, {AB_KEY, AB_TRANS_RETRIEVAL});
635 G_OBJECT_WARN_INVALID_PROPERTY_ID(
object, prop_id, pspec);
643 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
645 gobject_class->dispose = gnc_account_dispose;
646 gobject_class->finalize = gnc_account_finalize;
647 gobject_class->set_property = gnc_account_set_property;
648 gobject_class->get_property = gnc_account_get_property;
650 g_object_class_install_property
653 g_param_spec_string (
"name",
655 "The accountName is an arbitrary string " 656 "assigned by the user. It is intended to " 657 "a short, 5 to 30 character long string " 658 "that is displayed by the GUI as the " 659 "account mnemonic. Account names may be " 660 "repeated. but no two accounts that share " 661 "a parent may have the same name.",
663 static_cast<GParamFlags>(G_PARAM_READWRITE)));
665 g_object_class_install_property
668 g_param_spec_string (
"fullname",
670 "The name of the account concatenated with " 671 "all its parent account names to indicate " 674 static_cast<GParamFlags>(G_PARAM_READABLE)));
676 g_object_class_install_property
679 g_param_spec_string (
"code",
681 "The account code is an arbitrary string " 682 "assigned by the user. It is intended to " 683 "be reporting code that is a synonym for " 686 static_cast<GParamFlags>(G_PARAM_READWRITE)));
688 g_object_class_install_property
691 g_param_spec_string (
"description",
692 "Account Description",
693 "The account description is an arbitrary " 694 "string assigned by the user. It is intended " 695 "to be a longer, 1-5 sentence description of " 696 "what this account is all about.",
698 static_cast<GParamFlags>(G_PARAM_READWRITE)));
700 g_object_class_install_property
703 g_param_spec_string (
"color",
705 "The account color is a color string assigned " 706 "by the user. It is intended to highlight the " 707 "account based on the users wishes.",
709 static_cast<GParamFlags>(G_PARAM_READWRITE)));
711 g_object_class_install_property
714 g_param_spec_string (
"notes",
716 "The account notes is an arbitrary provided " 717 "for the user to attach any other text that " 718 "they would like to associate with the account.",
720 static_cast<GParamFlags>(G_PARAM_READWRITE)));
722 g_object_class_install_property
725 g_param_spec_int (
"type",
727 "The account type, picked from the enumerated list " 728 "that includes ACCT_TYPE_BANK, ACCT_TYPE_STOCK, " 729 "ACCT_TYPE_CREDIT, ACCT_TYPE_INCOME, etc.",
733 static_cast<GParamFlags>(G_PARAM_READWRITE)));
735 g_object_class_install_property
738 g_param_spec_object (
"commodity",
740 "The commodity field denotes the kind of " 741 "'stuff' stored in this account, whether " 742 "it is USD, gold, stock, etc.",
744 static_cast<GParamFlags>(G_PARAM_READWRITE)));
746 g_object_class_install_property
749 g_param_spec_int (
"commodity-scu",
751 "The smallest fraction of the commodity that is " 752 "tracked. This number is used as the denominator " 753 "value in 1/x, so a value of 100 says that the " 754 "commodity can be divided into hundredths. E.G." 755 "1 USD can be divided into 100 cents.",
759 static_cast<GParamFlags>(G_PARAM_READWRITE)));
761 g_object_class_install_property
764 g_param_spec_boolean (
"non-std-scu",
766 "TRUE if the account SCU doesn't match " 767 "the commodity SCU. This indicates a case " 768 "where the two were accidentally set to " 769 "mismatched values in older versions of " 772 static_cast<GParamFlags>(G_PARAM_READWRITE)));
774 g_object_class_install_property
777 g_param_spec_boolean(
"sort-dirty",
779 "TRUE if the splits in the account needs to be " 780 "resorted. This flag is set by the accounts " 781 "code for certain internal modifications, or " 782 "when external code calls the engine to say a " 783 "split has been modified in a way that may " 784 "affect the sort order of the account. Note: " 785 "This value can only be set to TRUE.",
787 static_cast<GParamFlags>(G_PARAM_READWRITE)));
789 g_object_class_install_property
792 g_param_spec_boolean(
"balance-dirty",
794 "TRUE if the running balances in the account " 795 "needs to be recalculated. This flag is set " 796 "by the accounts code for certain internal " 797 "modifications, or when external code calls " 798 "the engine to say a split has been modified. " 799 "Note: This value can only be set to TRUE.",
801 static_cast<GParamFlags>(G_PARAM_READWRITE)));
803 g_object_class_install_property
806 g_param_spec_boxed(
"start-balance",
808 "The starting balance for the account. This " 809 "parameter is intended for use with backends that " 810 "do not return the complete list of splits for an " 811 "account, but rather return a partial list. In " 812 "such a case, the backend will typically return " 813 "all of the splits after some certain date, and " 814 "the 'starting balance' will represent the " 815 "summation of the splits up to that date.",
817 static_cast<GParamFlags>(G_PARAM_READWRITE)));
819 g_object_class_install_property
821 PROP_START_NOCLOSING_BALANCE,
822 g_param_spec_boxed(
"start-noclosing-balance",
823 "Starting No-closing Balance",
824 "The starting balance for the account, ignoring closing." 825 "This parameter is intended for use with backends " 826 "that do not return the complete list of splits " 827 "for an account, but rather return a partial " 828 "list. In such a case, the backend will " 829 "typically return all of the splits after " 830 "some certain date, and the 'starting noclosing " 831 "balance' will represent the summation of the " 832 "splits up to that date, ignoring closing splits.",
834 static_cast<GParamFlags>(G_PARAM_READWRITE)));
836 g_object_class_install_property
838 PROP_START_CLEARED_BALANCE,
839 g_param_spec_boxed(
"start-cleared-balance",
840 "Starting Cleared Balance",
841 "The starting cleared balance for the account. " 842 "This parameter is intended for use with backends " 843 "that do not return the complete list of splits " 844 "for an account, but rather return a partial " 845 "list. In such a case, the backend will " 846 "typically return all of the splits after " 847 "some certain date, and the 'starting cleared " 848 "balance' will represent the summation of the " 849 "splits up to that date.",
851 static_cast<GParamFlags>(G_PARAM_READWRITE)));
853 g_object_class_install_property
855 PROP_START_RECONCILED_BALANCE,
856 g_param_spec_boxed(
"start-reconciled-balance",
857 "Starting Reconciled Balance",
858 "The starting reconciled balance for the " 859 "account. This parameter is intended for use " 860 "with backends that do not return the complete " 861 "list of splits for an account, but rather return " 862 "a partial list. In such a case, the backend " 863 "will typically return all of the splits after " 864 "some certain date, and the 'starting reconciled " 865 "balance' will represent the summation of the " 866 "splits up to that date.",
868 static_cast<GParamFlags>(G_PARAM_READWRITE)));
870 g_object_class_install_property
873 g_param_spec_boxed(
"end-balance",
874 "Ending Account Balance",
875 "This is the current ending balance for the " 876 "account. It is computed from the sum of the " 877 "starting balance and all splits in the account.",
881 g_object_class_install_property
883 PROP_END_NOCLOSING_BALANCE,
884 g_param_spec_boxed(
"end-noclosing-balance",
885 "Ending Account Noclosing Balance",
886 "This is the current ending no-closing balance for " 887 "the account. It is computed from the sum of the " 888 "starting balance and all cleared splits in the " 893 g_object_class_install_property
895 PROP_END_CLEARED_BALANCE,
896 g_param_spec_boxed(
"end-cleared-balance",
897 "Ending Account Cleared Balance",
898 "This is the current ending cleared balance for " 899 "the account. It is computed from the sum of the " 900 "starting balance and all cleared splits in the " 905 g_object_class_install_property
907 PROP_END_RECONCILED_BALANCE,
908 g_param_spec_boxed(
"end-reconciled-balance",
909 "Ending Account Reconciled Balance",
910 "This is the current ending reconciled balance " 911 "for the account. It is computed from the sum of " 912 "the starting balance and all reconciled splits " 915 static_cast<GParamFlags>(G_PARAM_READABLE)));
917 g_object_class_install_property
920 g_param_spec_pointer (
"policy",
922 "The account lots policy.",
923 static_cast<GParamFlags>(G_PARAM_READWRITE)));
925 g_object_class_install_property
928 g_param_spec_int (
"acct-mark",
934 static_cast<GParamFlags>(G_PARAM_READWRITE)));
936 g_object_class_install_property
939 g_param_spec_boolean (
"tax-related",
941 "Whether the account maps to an entry on an " 942 "income tax document.",
944 static_cast<GParamFlags>(G_PARAM_READWRITE)));
946 g_object_class_install_property
948 PROP_IS_OPENING_BALANCE,
949 g_param_spec_boolean (
"opening-balance",
951 "Whether the account holds opening balances",
953 static_cast<GParamFlags>(G_PARAM_READWRITE)));
955 g_object_class_install_property
958 g_param_spec_string (
"tax-code",
960 "This is the code for mapping an account to a " 961 "specific entry on a taxable document. In the " 962 "United States it is used to transfer totals " 963 "into tax preparation software.",
965 static_cast<GParamFlags>(G_PARAM_READWRITE)));
967 g_object_class_install_property
970 g_param_spec_string (
"tax-source",
972 "This specifies where exported name comes from.",
974 static_cast<GParamFlags>(G_PARAM_READWRITE)));
976 g_object_class_install_property
978 PROP_TAX_COPY_NUMBER,
979 g_param_spec_int64 (
"tax-copy-number",
981 "This specifies the copy number of the tax " 986 static_cast<GParamFlags>(G_PARAM_READWRITE)));
988 g_object_class_install_property
991 g_param_spec_boolean (
"hidden",
993 "Whether the account should be hidden in the " 996 static_cast<GParamFlags>(G_PARAM_READWRITE)));
998 g_object_class_install_property
1001 g_param_spec_boolean (
"auto-interest-transfer",
1003 "Whether an interest transfer should be automatically " 1004 "added before reconcile.",
1006 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1008 g_object_class_install_property
1011 g_param_spec_boolean (
"placeholder",
1013 "Whether the account is a placeholder account which does not " 1014 "allow transactions to be created, edited or deleted.",
1016 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1018 g_object_class_install_property
1021 g_param_spec_string (
"filter",
1023 "The account filter is a value saved to allow " 1024 "filters to be recalled.",
1026 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1028 g_object_class_install_property
1031 g_param_spec_string (
"sort-order",
1032 "Account Sort Order",
1033 "The account sort order is a value saved to allow " 1034 "the sort order to be recalled.",
1036 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1038 g_object_class_install_property
1041 g_param_spec_boolean (
"sort-reversed",
1042 "Account Sort Reversed",
1043 "Parameter to store whether the sort order is reversed or not.",
1045 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1047 g_object_class_install_property
1050 g_param_spec_int64 (
"lot-next-id",
1052 "Tracks the next id to use in gnc_lot_make_default.",
1056 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1058 g_object_class_install_property
1060 PROP_ONLINE_ACCOUNT,
1061 g_param_spec_string (
"online-id",
1062 "Online Account ID",
1063 "The online account which corresponds to this " 1064 "account for OFX import",
1066 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1068 g_object_class_install_property
1070 PROP_IMP_APPEND_TEXT,
1071 g_param_spec_boolean (
"import-append-text",
1072 "Import Append Text",
1073 "Saved state of Append checkbox for setting initial " 1074 "value next time this account is imported.",
1076 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1078 g_object_class_install_property(
1080 PROP_OFX_INCOME_ACCOUNT,
1081 g_param_spec_boxed(
"ofx-income-account",
1082 "Associated income account",
1083 "Used by the OFX importer.",
1085 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1087 g_object_class_install_property
1090 g_param_spec_string (
"ab-account-id",
1091 "AQBanking Account ID",
1092 "The AqBanking account which corresponds to this " 1093 "account for AQBanking import",
1095 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1096 g_object_class_install_property
1099 g_param_spec_string (
"ab-bank-code",
1100 "AQBanking Bank Code",
1101 "The online account which corresponds to this " 1102 "account for AQBanking import",
1104 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1106 g_object_class_install_property
1108 PROP_AB_ACCOUNT_UID,
1109 g_param_spec_int64 (
"ab-account-uid",
1110 "AQBanking Account UID",
1111 "Tracks the next id to use in gnc_lot_make_default.",
1115 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1117 g_object_class_install_property
1119 PROP_AB_TRANS_RETRIEVAL,
1120 g_param_spec_boxed(
"ab-trans-retrieval",
1121 "AQBanking Last Transaction Retrieval",
1122 "The time of the last transaction retrieval for this " 1125 static_cast<GParamFlags>(G_PARAM_READWRITE)));
1132 ENTER (
"book=%p\n", book);
1135 LEAVE (
"account=%p\n", acc);
1142 gnc_account_foreach_split (
const Account *acc, std::function<
void(Split*)> func)
1144 gnc_account_foreach_split_between_dates (acc, {}, {},
false, func);
1148 gnc_account_foreach_split_until_date (
const Account *acc,
time64 end_date,
1149 std::function<
void(Split*)> f)
1151 gnc_account_foreach_split_between_dates (acc, {}, end_date,
false, f);
1159 if (!GNC_IS_ACCOUNT (acc))
1162 const auto& splits{GET_PRIVATE(acc)->splits};
1165 auto latest = std::find_if(splits.rbegin(), splits.rend(), predicate);
1166 return (latest == splits.rend()) ?
nullptr : *latest;
1170 auto earliest = std::find_if(splits.begin(), splits.end(), predicate);
1171 return (earliest == splits.end()) ?
nullptr : *earliest;
1179 gnc_account_get_book(
const Account *account)
1181 if (!account)
return nullptr;
1189 gnc_coll_get_root_account (QofCollection *col)
1191 if (!col)
return nullptr;
1196 gnc_coll_set_root_account (QofCollection *col,
Account *root)
1202 old_root = gnc_coll_get_root_account (col);
1203 if (old_root == root)
return;
1208 rpriv = GET_PRIVATE(root);
1216 qof_collection_set_data (col, root);
1226 gnc_book_get_root_account (
QofBook *book)
1231 if (!book)
return nullptr;
1233 root = gnc_coll_get_root_account (col);
1245 if (root && gnc_account_get_book(root) != book)
1247 PERR (
"cannot mix and match books freely!");
1252 gnc_coll_set_root_account (col, root);
1263 g_return_val_if_fail (book,
nullptr);
1265 acc =
static_cast<Account*
>(g_object_new (GNC_TYPE_ACCOUNT,
nullptr));
1266 xaccInitAccount (acc, book);
1279 rpriv = GET_PRIVATE(root);
1283 mark_account (root);
1285 gnc_book_set_root_account(book, root);
1295 g_return_val_if_fail(GNC_IS_ACCOUNT(from),
nullptr);
1296 g_return_val_if_fail(QOF_IS_BOOK(book),
nullptr);
1299 ret =
static_cast<Account*
>(g_object_new (GNC_TYPE_ACCOUNT,
nullptr));
1300 g_return_val_if_fail (ret,
nullptr);
1302 from_priv = GET_PRIVATE(from);
1303 priv = GET_PRIVATE(ret);
1304 xaccInitAccount (ret, book);
1309 priv->type = from_priv->type;
1315 qof_instance_copy_kvp (QOF_INSTANCE (ret), QOF_INSTANCE (from));
1322 priv->commodity_scu = from_priv->commodity_scu;
1323 priv->non_standard_scu = from_priv->non_standard_scu;
1325 qof_instance_set_dirty(&ret->inst);
1334 xaccFreeOneChildAccount (
Account *acc)
1338 if (qof_instance_get_editlevel(acc) == 0)
1344 xaccFreeAccountChildren (
Account *acc)
1346 auto priv{GET_PRIVATE(acc)};
1348 auto children = priv->children;
1349 std::for_each (children.begin(), children.end(), xaccFreeOneChildAccount);
1352 priv->children.clear();
1360 xaccFreeAccount (
Account *acc)
1365 g_return_if_fail(GNC_IS_ACCOUNT(acc));
1367 priv = GET_PRIVATE(acc);
1374 qof_instance_set_destroying(acc, TRUE);
1376 if (!priv->children.empty())
1378 PERR (
" instead of calling xaccFreeAccount(), please call\n" 1379 " xaccAccountBeginEdit(); xaccAccountDestroy();\n");
1382 xaccFreeAccountChildren(acc);
1388 PERR (
" instead of calling xaccFreeAccount(), please call\n" 1389 " xaccAccountBeginEdit(); xaccAccountDestroy();\n");
1391 for (lp = priv->lots; lp; lp = lp->next)
1393 GNCLot *lot =
static_cast<GNCLot*
>(lp->data);
1394 gnc_lot_destroy (lot);
1396 g_list_free (priv->lots);
1397 priv->lots =
nullptr;
1404 if (!priv->splits.empty())
1406 PERR (
" instead of calling xaccFreeAccount(), please call\n" 1407 " xaccAccountBeginEdit(); xaccAccountDestroy();\n");
1409 qof_instance_reset_editlevel(acc);
1411 for (
auto s : priv->splits)
1424 priv->accountName = priv->accountCode = priv->description =
nullptr;
1429 priv->last_num =
nullptr;
1430 priv->tax_us_code =
nullptr;
1431 priv->tax_us_pns =
nullptr;
1432 priv->color =
nullptr;
1433 priv->sort_order =
nullptr;
1434 priv->notes =
nullptr;
1435 priv->filter =
nullptr;
1437 priv->parent =
nullptr;
1439 priv->balance = gnc_numeric_zero();
1440 priv->noclosing_balance = gnc_numeric_zero();
1441 priv->cleared_balance = gnc_numeric_zero();
1442 priv->reconciled_balance = gnc_numeric_zero();
1446 priv->commodity =
nullptr;
1448 priv->balance_dirty = FALSE;
1449 priv->has_stock_split =
false;
1450 priv->sort_dirty = FALSE;
1451 priv->splits.~SplitsVec();
1452 priv->children.~AccountVec();
1453 g_hash_table_destroy (priv->splits_hash);
1456 g_object_unref(acc);
1466 g_return_if_fail(acc);
1478 PERR(
"commit error: %d", errcode);
1479 gnc_engine_signal_commit_error( errcode );
1487 priv = GET_PRIVATE(acc);
1490 xaccFreeAccount(acc);
1494 destroy_pending_splits_for_account(
QofInstance *ent, gpointer acc)
1496 Transaction *trans = (Transaction *) ent;
1500 while ((split = xaccTransFindSplitByAccount(trans, static_cast<Account*>(acc))))
1510 g_return_if_fail(acc);
1515 priv = GET_PRIVATE(acc);
1520 qof_instance_increase_editlevel(acc);
1523 xaccFreeAccountChildren(acc);
1525 PINFO (
"freeing splits for account %p (%s)",
1526 acc, priv->accountName ? priv->accountName :
"(null)");
1535 for_each(priv->splits.rbegin(), priv->splits.rend(), [](Split *s) {
1540 priv->splits.clear();
1541 g_hash_table_remove_all (priv->splits_hash);
1555 qof_collection_foreach(col, destroy_pending_splits_for_account, acc);
1558 for (
auto lp = priv->lots; lp; lp = lp->next)
1560 GNCLot *lot =
static_cast<GNCLot*
>(lp->data);
1561 gnc_lot_destroy (lot);
1564 g_list_free(priv->lots);
1565 priv->lots =
nullptr;
1567 qof_instance_set_dirty(&acc->inst);
1568 qof_instance_decrease_editlevel(acc);
1572 xaccAccountBringUpToDate(acc);
1581 g_return_if_fail(GNC_IS_ACCOUNT(acc));
1583 qof_instance_set_destroying(acc, TRUE);
1591 auto priv = GET_PRIVATE(acc);
1592 std::vector<Transaction*> transactions;
1593 transactions.reserve(priv->splits.size());
1594 std::transform(priv->splits.begin(), priv->splits.end(),
1595 back_inserter(transactions),
1596 [](
auto split) {
return split->parent; });
1597 std::stable_sort(transactions.begin(), transactions.end());
1598 transactions.erase(std::unique(transactions.begin(), transactions.end()),
1599 transactions.end());
1601 std::for_each(transactions.rbegin(), transactions.rend(),
1610 xaccAcctChildrenEqual(
const AccountVec& na,
1611 const AccountVec& nb,
1612 gboolean check_guids)
1614 if (na.size() != nb.size())
1616 PINFO (
"Accounts have different numbers of children");
1622 auto it_b = std::find_if (nb.begin(), nb.end(), [aa](
auto ab) ->
bool 1624 if (!aa)
return (!ab);
1625 if (!ab)
return false;
1626 auto code_a{GET_PRIVATE(aa)->accountCode};
1627 auto code_b{GET_PRIVATE(ab)->accountCode};
1628 if ((code_a && *code_a) || (code_b && *code_b))
return !g_strcmp0 (code_a, code_b);
1629 return !g_strcmp0 (GET_PRIVATE(aa)->accountName, GET_PRIVATE(ab)->accountName);
1632 if (it_b == nb.end())
1634 PINFO (
"Unable to find matching child account.");
1645 PWARN (
"accounts %s and %s differ", sa, sb);
1659 if (!aa && !ab)
return TRUE;
1661 g_return_val_if_fail(GNC_IS_ACCOUNT(aa), FALSE);
1662 g_return_val_if_fail(GNC_IS_ACCOUNT(ab), FALSE);
1664 priv_aa = GET_PRIVATE(aa);
1665 priv_ab = GET_PRIVATE(ab);
1666 if (priv_aa->type != priv_ab->type)
1668 PWARN (
"types differ: %d vs %d", priv_aa->type, priv_ab->type);
1672 if (g_strcmp0(priv_aa->accountName, priv_ab->accountName) != 0)
1674 PWARN (
"names differ: %s vs %s", priv_aa->accountName, priv_ab->accountName);
1678 if (g_strcmp0(priv_aa->accountCode, priv_ab->accountCode) != 0)
1680 PWARN (
"codes differ: %s vs %s", priv_aa->accountCode, priv_ab->accountCode);
1684 if (g_strcmp0(priv_aa->description, priv_ab->description) != 0)
1686 PWARN (
"descriptions differ: %s vs %s", priv_aa->description, priv_ab->description);
1692 PWARN (
"commodities differ");
1700 PWARN (
"GUIDs differ");
1705 if (qof_instance_compare_kvp (QOF_INSTANCE (aa), QOF_INSTANCE (ab)) != 0)
1710 frame_a = qof_instance_kvp_as_string (QOF_INSTANCE (aa));
1711 frame_b = qof_instance_kvp_as_string (QOF_INSTANCE (ab));
1713 PWARN (
"kvp frames differ:\n%s\n\nvs\n\n%s", frame_a, frame_b);
1729 PWARN (
"starting balances differ: %s vs %s", str_a, str_b);
1738 priv_ab->starting_noclosing_balance))
1746 PWARN (
"starting noclosing balances differ: %s vs %s", str_a, str_b);
1754 priv_ab->starting_cleared_balance))
1762 PWARN (
"starting cleared balances differ: %s vs %s", str_a, str_b);
1771 priv_ab->starting_reconciled_balance))
1779 PWARN (
"starting reconciled balances differ: %s vs %s", str_a, str_b);
1795 PWARN (
"balances differ: %s vs %s", str_a, str_b);
1811 PWARN (
"noclosing balances differ: %s vs %s", str_a, str_b);
1826 PWARN (
"cleared balances differ: %s vs %s", str_a, str_b);
1834 if (!
gnc_numeric_equal(priv_aa->reconciled_balance, priv_ab->reconciled_balance))
1842 PWARN (
"reconciled balances differ: %s vs %s", str_a, str_b);
1852 if (!std::equal (priv_aa->splits.begin(), priv_aa->splits.end(),
1853 priv_ab->splits.begin(), priv_ab->splits.end(),
1854 [check_guids](
auto sa,
auto sb)
1857 PWARN (
"splits differ");
1861 if (!xaccAcctChildrenEqual(priv_aa->children, priv_ab->children, check_guids))
1863 PWARN (
"children differ");
1877 g_return_if_fail(GNC_IS_ACCOUNT(acc));
1882 priv = GET_PRIVATE(acc);
1883 priv->sort_dirty = TRUE;
1891 g_return_if_fail(GNC_IS_ACCOUNT(acc));
1896 priv = GET_PRIVATE(acc);
1897 priv->balance_dirty = TRUE;
1904 g_return_if_fail (GNC_IS_ACCOUNT (acc));
1909 priv = GET_PRIVATE (acc);
1910 priv->defer_bal_computation = defer;
1918 priv = GET_PRIVATE (acc);
1919 return priv->defer_bal_computation;
1926 static bool split_cmp_less (
const Split* a,
const Split* b)
1936 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
1937 g_return_val_if_fail(GNC_IS_SPLIT(s), FALSE);
1939 priv = GET_PRIVATE(acc);
1940 if (!g_hash_table_add (priv->splits_hash, s))
1943 priv->splits.push_back (s);
1945 if (qof_instance_get_editlevel(acc) == 0)
1946 std::sort (priv->splits.begin(), priv->splits.end(), split_cmp_less);
1948 priv->sort_dirty =
true;
1955 priv->balance_dirty = TRUE;
1966 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
1967 g_return_val_if_fail(GNC_IS_SPLIT(s), FALSE);
1969 priv = GET_PRIVATE(acc);
1971 if (!g_hash_table_remove (priv->splits_hash, s))
1976 if (s == priv->splits.back())
1977 priv->splits.pop_back();
1979 priv->splits.erase (std::remove (priv->splits.begin(), priv->splits.end(), s),
1980 priv->splits.end());
1987 priv->balance_dirty = TRUE;
1997 g_return_if_fail(GNC_IS_ACCOUNT(acc));
1999 priv = GET_PRIVATE(acc);
2000 if (!priv->sort_dirty || (!force && qof_instance_get_editlevel(acc) > 0))
2002 std::sort (priv->splits.begin(), priv->splits.end(), split_cmp_less);
2003 priv->sort_dirty = FALSE;
2004 priv->balance_dirty = TRUE;
2008 xaccAccountBringUpToDate(
Account *acc)
2024 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2025 g_return_if_fail(guid);
2028 PINFO(
"acct=%p", acc);
2030 qof_instance_set_guid (&acc->inst, guid);
2031 qof_instance_set_dirty(&acc->inst);
2042 if (!guid || !book)
return nullptr;
2055 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2057 priv = GET_PRIVATE(acc);
2066 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2077 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2079 priv = GET_PRIVATE(acc);
2081 std::for_each (priv->children.begin(), priv->children.end(),
2091 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
2093 return GET_PRIVATE(acc)->policy;
2101 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2103 priv = GET_PRIVATE(acc);
2111 xaccAccountRemoveLot (
Account *acc, GNCLot *lot)
2115 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2116 g_return_if_fail(GNC_IS_LOT(lot));
2118 priv = GET_PRIVATE(acc);
2119 g_return_if_fail(priv->lots);
2121 ENTER (
"(acc=%p, lot=%p)", acc, lot);
2122 priv->lots = g_list_remove(priv->lots, lot);
2123 qof_event_gen (QOF_INSTANCE(lot), QOF_EVENT_REMOVE,
nullptr);
2125 LEAVE (
"(acc=%p, lot=%p)", acc, lot);
2132 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2133 g_return_if_fail(GNC_IS_LOT(lot));
2140 ENTER (
"(acc=%p, lot=%p)", acc, lot);
2145 auto priv = GET_PRIVATE(lot_acc);
2146 priv->lots = g_list_remove(priv->lots, lot);
2150 auto priv = GET_PRIVATE(acc);
2151 priv->lots = g_list_prepend(priv->lots, lot);
2152 gnc_lot_set_account(lot, acc);
2162 LEAVE (
"(acc=%p, lot=%p)", acc, lot);
2168 xaccPreSplitMove (Split *split)
2174 xaccPostSplitMove (Split *split,
Account *accto)
2178 xaccSplitSetAccount(split, accto);
2190 g_return_if_fail(GNC_IS_ACCOUNT(accfrom));
2191 g_return_if_fail(GNC_IS_ACCOUNT(accto));
2194 from_priv = GET_PRIVATE(accfrom);
2195 if (from_priv->splits.empty() || accfrom == accto)
2200 ENTER (
"(accfrom=%p, accto=%p)", accfrom, accto);
2205 std::for_each (from_priv->splits.begin(), from_priv->splits.end(), xaccPreSplitMove);
2222 auto splits = from_priv->splits;
2223 std::for_each (splits.begin(), splits.end(), [accto](
auto s){ xaccPostSplitMove (s, accto); });
2226 g_assert(from_priv->splits.empty());
2227 g_assert(from_priv->lots ==
nullptr);
2231 LEAVE (
"(accfrom=%p, accto=%p)", accfrom, accto);
2266 if (
nullptr == acc)
return;
2268 auto priv = GET_PRIVATE(acc);
2269 if (qof_instance_get_editlevel(acc) > 0)
return;
2270 if (!priv->balance_dirty || priv->defer_bal_computation)
return;
2274 auto balance = priv->starting_balance;
2275 auto noclosing_balance = priv->starting_noclosing_balance;
2276 auto cleared_balance = priv->starting_cleared_balance;
2277 auto reconciled_balance = priv->starting_reconciled_balance;
2278 auto has_stock_split =
false;
2280 PINFO (
"acct=%s starting baln=%" G_GINT64_FORMAT
"/%" G_GINT64_FORMAT,
2281 priv->accountName, balance.num, balance.denom);
2282 for (
auto split : priv->splits)
2290 auto new_balance = gnc_numeric_add_fixed(balance, amt);
2296 for (
auto psplit : priv->splits)
2298 if (psplit == split)
2304 balance = new_balance;
2305 has_stock_split =
true;
2309 split->adjusted_amount = amt;
2310 balance = gnc_numeric_add_fixed(balance, amt);
2313 if (
NREC != split->reconciled)
2315 cleared_balance = gnc_numeric_add_fixed(cleared_balance, amt);
2318 if (
YREC == split->reconciled ||
2319 FREC == split->reconciled)
2321 reconciled_balance =
2322 gnc_numeric_add_fixed(reconciled_balance, amt);
2326 noclosing_balance = gnc_numeric_add_fixed(noclosing_balance, amt);
2328 split->balance = balance;
2329 split->noclosing_balance = noclosing_balance;
2330 split->cleared_balance = cleared_balance;
2331 split->reconciled_balance = reconciled_balance;
2335 priv->balance = balance;
2336 priv->noclosing_balance = noclosing_balance;
2337 priv->cleared_balance = cleared_balance;
2338 priv->reconciled_balance = reconciled_balance;
2339 priv->balance_dirty = FALSE;
2340 priv->has_stock_split = has_stock_split;
2349 static constexpr std::array<int,NUM_ACCOUNT_TYPES> typeorder =
2357 static constexpr
auto revorder = []
2359 std::array<int, NUM_ACCOUNT_TYPES> rv{};
2360 for (
auto& r : rv) r = -1;
2362 rv[typeorder[i]] = i;
2370 const char *da, *db;
2373 if (aa == ab)
return 0;
2377 priv_aa = GET_PRIVATE(aa);
2378 priv_ab = GET_PRIVATE(ab);
2381 da = priv_aa->accountCode;
2382 db = priv_ab->accountCode;
2385 result = g_strcmp0 (da, db);
2394 if (ta < tb)
return -1;
2395 if (ta > tb)
return +1;
2398 da = priv_aa->accountName;
2399 db = priv_ab->accountName;
2423 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2427 priv = GET_PRIVATE(acc);
2428 if (priv->type == tip)
2433 priv->balance_dirty = TRUE;
2444 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2445 g_return_if_fail(str);
2448 priv = GET_PRIVATE(acc);
2449 if (g_strcmp0(str, priv->accountName) == 0)
2464 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2467 priv = GET_PRIVATE(acc);
2468 if (g_strcmp0(str, priv->accountCode) == 0)
2483 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2486 priv = GET_PRIVATE(acc);
2487 if (g_strcmp0(str, priv->description) == 0)
2497 set_kvp_gnc_numeric_path (
Account *acc,
const std::vector<std::string>& path,
2498 std::optional<gnc_numeric> value)
2501 qof_instance_set_path_kvp<gnc_numeric> (QOF_INSTANCE(acc), value, path);
2505 static std::optional<gnc_numeric>
2506 get_kvp_gnc_numeric_path (
const Account *acc,
const Path& path)
2508 return qof_instance_get_path_kvp<gnc_numeric> (QOF_INSTANCE(acc), path);
2512 set_kvp_string_path (
Account *acc, std::vector<std::string>
const & path,
2515 std::optional<const char*> val;
2516 if (value && *value)
2517 val = g_strdup(value);
2520 qof_instance_set_path_kvp<const char*> (QOF_INSTANCE(acc), val, path);
2525 get_kvp_string_path (
const Account *acc,
const Path& path)
2527 auto rv{qof_instance_get_path_kvp<const char*> (QOF_INSTANCE(acc), path)};
2528 return rv ? *rv :
nullptr;
2532 set_kvp_account_path (
Account* acc,
const Path& path,
const Account* kvp_account)
2534 std::optional<GncGUID*> val;
2539 qof_instance_set_path_kvp<GncGUID*> (QOF_INSTANCE(acc), val, path);
2544 get_kvp_account_path (
const Account *acc,
const Path& path)
2546 auto val{qof_instance_get_path_kvp<GncGUID*> (QOF_INSTANCE(acc), path)};
2551 set_kvp_boolean_path (
Account *acc,
const Path& path, gboolean option)
2553 set_kvp_string_path (acc, path, option ?
"true" :
nullptr);
2557 get_kvp_boolean_path (
const Account *acc,
const Path& path)
2559 auto slot{QOF_INSTANCE(acc)->kvp_data->get_slot(path)};
2560 if (!slot)
return false;
2561 switch (slot->get_type())
2563 case KvpValueImpl::Type::INT64:
2564 return slot->get<int64_t>() != 0;
2565 case KvpValueImpl::Type::STRING:
2566 return g_strcmp0 (slot->get<
const char*>(),
"true") == 0;
2573 set_kvp_int64_path (
Account *acc,
const Path& path, std::optional<gint64> value)
2576 qof_instance_set_path_kvp<int64_t> (QOF_INSTANCE(acc), value, path);
2580 static const std::optional<gint64>
2581 get_kvp_int64_path (
const Account *acc,
const Path& path)
2583 return qof_instance_get_path_kvp<int64_t> (QOF_INSTANCE(acc), path);
2587 get_kvp_guid_path (
const Account *acc,
const Path& path)
2589 auto val{qof_instance_get_path_kvp<GncGUID*> (QOF_INSTANCE(acc), path)};
2596 set_kvp_string_path (acc, {
"color"}, str);
2602 set_kvp_string_path (acc, {
"filter"}, str);
2608 set_kvp_string_path (acc, {
"sort-order"}, str);
2614 set_kvp_boolean_path (acc, {
"sort-reversed"}, sortreversed);
2622 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2623 g_return_if_fail(GNC_IS_ACCOUNT(parent));
2625 parent_acc = GNC_ACCOUNT(parent);
2629 mark_account (parent_acc);
2638 set_kvp_string_path (acc, {
"notes"}, str);
2644 g_return_if_fail (GNC_IS_ACCOUNT(acc));
2645 set_kvp_string_path (acc, {KEY_ONLINE_ID}, id);
2652 g_return_if_fail (GNC_IS_ACCOUNT(acc));
2653 g_return_if_fail (tag && *tag);
2655 set_kvp_account_path (acc, {
"associated-account", tag}, assoc_acct);
2664 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2665 g_return_if_fail(GNC_IS_COMMODITY(com));
2668 priv = GET_PRIVATE(acc);
2669 if (com == priv->commodity)
2674 priv->commodity = com;
2677 priv->non_standard_scu = FALSE;
2680 for (
auto s : priv->splits)
2689 priv->sort_dirty = TRUE;
2690 priv->balance_dirty = TRUE;
2707 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2709 priv = GET_PRIVATE(acc);
2711 priv->commodity_scu = scu;
2713 priv->non_standard_scu = TRUE;
2721 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0);
2722 return GET_PRIVATE(acc)->commodity_scu;
2730 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0);
2732 priv = GET_PRIVATE(acc);
2733 if (priv->non_standard_scu || !priv->commodity)
2734 return priv->commodity_scu;
2743 g_return_if_fail(GNC_IS_ACCOUNT(acc));
2745 priv = GET_PRIVATE(acc);
2746 if (priv->non_standard_scu == flag)
2749 priv->non_standard_scu = flag;
2757 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), 0);
2758 return GET_PRIVATE(acc)->non_standard_scu;
2768 if ((!acc) || (!currency))
return;
2771 set_kvp_string_path (acc, {
"old-currency"}, s);
2775 auto commodity = gnc_commodity_table_lookup_unique (
table, s);
2787 g_return_if_fail (GNC_IS_ACCOUNT(acc));
2792 auto children = GET_PRIVATE(acc)->children;
2793 for (
auto child : children)
2801 account_foreach_descendant_sorted (
const Account *acc, std::function<
void(
Account*)> account_cb)
2803 g_return_if_fail (GNC_IS_ACCOUNT(acc));
2805 auto children = GET_PRIVATE(acc)->children;
2806 std::sort (children.begin(), children.end(),
2809 for (
auto child : children)
2812 account_foreach_descendant_sorted (child, account_cb);
2824 g_assert(GNC_IS_ACCOUNT(new_parent));
2825 g_assert(GNC_IS_ACCOUNT(child));
2828 ppriv = GET_PRIVATE(new_parent);
2829 cpriv = GET_PRIVATE(child);
2830 old_parent = cpriv->parent;
2831 if (old_parent == new_parent)
2853 PWARN (
"reparenting accounts across books is not correctly supported\n");
2862 cpriv->parent = new_parent;
2863 ppriv->children.push_back (child);
2864 qof_instance_set_dirty(&new_parent->inst);
2865 qof_instance_set_dirty(&child->inst);
2888 if (!parent)
return;
2890 ppriv = GET_PRIVATE(parent);
2891 cpriv = GET_PRIVATE(child);
2893 if (cpriv->parent != parent)
2895 PERR (
"account not a child of parent");
2903 ppriv->children.erase (std::remove (ppriv->children.begin(), ppriv->children.end(), child),
2904 ppriv->children.end());
2910 cpriv->parent =
nullptr;
2918 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
2919 return GET_PRIVATE(acc)->parent;
2925 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
2936 g_return_val_if_fail(GNC_IS_ACCOUNT(account), FALSE);
2937 return (GET_PRIVATE(account)->parent ==
nullptr);
2943 g_return_val_if_fail(GNC_IS_ACCOUNT(account),
nullptr);
2944 auto& children = GET_PRIVATE(account)->children;
2945 return std::accumulate (children.rbegin(), children.rend(),
static_cast<GList*
>(
nullptr),
2952 g_return_val_if_fail(GNC_IS_ACCOUNT(account),
nullptr);
2959 g_return_val_if_fail(GNC_IS_ACCOUNT(account), 0);
2960 return GET_PRIVATE(account)->children.size();
2966 g_return_val_if_fail(GNC_IS_ACCOUNT(parent), -1);
2967 g_return_val_if_fail(GNC_IS_ACCOUNT(child), -1);
2968 auto& children = GET_PRIVATE(parent)->children;
2969 auto find_it = std::find (children.begin(), children.end(), child);
2970 return find_it == children.end() ? -1 : std::distance (children.begin(), find_it);
2976 g_return_val_if_fail(GNC_IS_ACCOUNT(parent),
nullptr);
2977 if ((
size_t)num >= GET_PRIVATE(parent)->children.size())
2979 return static_cast<Account*
>(GET_PRIVATE(parent)->children.at (num));
2996 g_return_val_if_fail(GNC_IS_ACCOUNT(account), 0);
2998 priv = GET_PRIVATE(account);
3001 account = priv->parent;
3002 priv = GET_PRIVATE(account);
3013 g_return_val_if_fail(GNC_IS_ACCOUNT(account), 0);
3015 priv = GET_PRIVATE(account);
3016 if (!priv->children.size())
3019 return 1 + std::accumulate (priv->children.begin(), priv->children.end(),
3020 0, [](
auto a,
auto b)
3027 GList* list =
nullptr;
3029 return g_list_reverse (list);
3035 GList* list =
nullptr;
3036 account_foreach_descendant_sorted (account, [&list](
auto a){ list = g_list_prepend (list, a); });
3037 return g_list_reverse (list);
3046 account_foreach_descendant_breadthfirst_until (
const Account *acc,
3050 g_return_val_if_fail (GNC_IS_ACCOUNT(acc),
nullptr);
3051 g_return_val_if_fail (thunk,
nullptr);
3053 auto& children{GET_PRIVATE(acc)->children};
3055 for (
auto acc : children)
3056 if (
auto result = thunk (acc, user_data))
3059 for (
auto acc: children)
3060 if (
auto result = account_foreach_descendant_breadthfirst_until (acc, thunk, user_data))
3067 is_acct_name (
Account *account, gpointer user_data)
3069 auto name {
static_cast<gchar*
>(user_data)};
3076 return (
Account*)account_foreach_descendant_breadthfirst_until (parent, is_acct_name, (
char*)name);
3080 is_acct_code (
Account *account, gpointer user_data)
3082 auto name {
static_cast<gchar*
>(user_data)};
3089 return (
Account*)account_foreach_descendant_breadthfirst_until (parent, is_acct_code, (
char*)code);
3093 is_opening_balance_account (
Account* account, gpointer data)
3095 gnc_commodity* commodity = GNC_COMMODITY(data);
3112 gnc_account_lookup_by_full_name_helper (
const Account *parent,
3115 g_return_val_if_fail(GNC_IS_ACCOUNT(parent),
nullptr);
3116 g_return_val_if_fail(names,
nullptr);
3119 for (
auto account : GET_PRIVATE(parent)->children)
3121 auto priv = GET_PRIVATE(account);
3122 if (g_strcmp0(priv->accountName, names[0]) == 0)
3126 if (names[1] ==
nullptr)
3130 if (priv->children.empty())
3134 if (
auto found = gnc_account_lookup_by_full_name_helper(account, &names[1]))
3152 g_return_val_if_fail(GNC_IS_ACCOUNT(any_acc),
nullptr);
3153 g_return_val_if_fail(name,
nullptr);
3156 rpriv = GET_PRIVATE(root);
3157 while (rpriv->parent)
3159 root = rpriv->parent;
3160 rpriv = GET_PRIVATE(root);
3163 found = gnc_account_lookup_by_full_name_helper(root, names);
3172 gnc_commodity* commodity)
3175 auto rpriv{GET_PRIVATE(root)};
3176 for (
auto account : rpriv->children)
3188 retval = g_list_prepend(retval, account);
3193 for (
auto account : rpriv->children)
3200 retval = g_list_concat(result, retval);
3210 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3211 g_return_if_fail(thunk);
3212 std::for_each (GET_PRIVATE(acc)->children.begin(), GET_PRIVATE(acc)->children.end(),
3213 [user_data, thunk](
auto a){ thunk (a, user_data); });
3229 gpointer result {
nullptr};
3231 g_return_val_if_fail (GNC_IS_ACCOUNT(acc),
nullptr);
3232 g_return_val_if_fail (thunk,
nullptr);
3234 for (
auto child : GET_PRIVATE(acc)->children)
3236 result = thunk (child, user_data);
3251 return GET_PRIVATE(acc)->type;
3255 qofAccountGetTypeString (
const Account *acc)
3257 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3262 qofAccountSetType (
Account *acc,
const char *type_string)
3264 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3265 g_return_if_fail(type_string);
3272 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3273 return GET_PRIVATE(acc)->accountName;
3276 std::vector<const Account*>
3277 gnc_account_get_all_parents (
const Account *account)
3279 std::vector<const Account*> rv;
3290 if (
nullptr == account)
3291 return g_strdup(
"");
3294 g_return_val_if_fail(GNC_IS_ACCOUNT(account), g_strdup(
""));
3296 auto path{gnc_account_get_all_parents (account)};
3297 auto seps_size{path.empty() ? 0 : strlen (account_separator) * (path.size() - 1)};
3298 auto alloc_size{std::accumulate (path.begin(), path.end(), seps_size,
3299 [](
auto sum,
auto acc)
3301 auto rv = g_new (
char, alloc_size + 1);
3304 std::for_each (path.rbegin(), path.rend(),
3308 p = stpcpy (p, account_separator);
3319 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3320 return GET_PRIVATE(acc)->accountCode;
3326 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3327 return GET_PRIVATE(acc)->description;
3333 return get_kvp_string_path (acc, {
"color"});
3339 return get_kvp_string_path (acc, {
"filter"});
3345 return get_kvp_string_path (acc, {
"sort-order"});
3351 return get_kvp_boolean_path (acc, {
"sort-reversed"});
3357 return get_kvp_string_path (acc, {
"notes"});
3363 g_return_val_if_fail (GNC_IS_ACCOUNT(acc),
nullptr);
3364 return get_kvp_string_path (acc, {KEY_ONLINE_ID});
3370 g_return_val_if_fail (tag && *tag,
nullptr);
3372 return get_kvp_account_path (acc, {
"associated-account", tag});
3379 if (
auto s = get_kvp_string_path (acc, {
"old-currency"}))
3382 return gnc_commodity_table_lookup_unique (
table, s);
3391 if (!GNC_IS_ACCOUNT(acc))
3393 return GET_PRIVATE(acc)->commodity;
3398 g_return_val_if_fail (GNC_IS_ACCOUNT (account),
nullptr);
3414 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3416 priv = GET_PRIVATE(acc);
3417 priv->starting_balance = start_baln;
3418 priv->balance_dirty = TRUE;
3423 const gnc_numeric start_baln)
3427 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3429 priv = GET_PRIVATE(acc);
3430 priv->starting_cleared_balance = start_baln;
3431 priv->balance_dirty = TRUE;
3436 const gnc_numeric start_baln)
3440 g_return_if_fail(GNC_IS_ACCOUNT(acc));
3442 priv = GET_PRIVATE(acc);
3443 priv->starting_reconciled_balance = start_baln;
3444 priv->balance_dirty = TRUE;
3450 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3451 return GET_PRIVATE(acc)->balance;
3457 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3458 return GET_PRIVATE(acc)->cleared_balance;
3464 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3465 return GET_PRIVATE(acc)->reconciled_balance;
3469 xaccAccountGetProjectedMinimumBalance (
const Account *acc)
3472 std::optional<gnc_numeric> minimum;
3474 auto before_today_end = [&minimum, today](
const Split *s) ->
bool 3484 return minimum ? *minimum : gnc_numeric_zero();
3490 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
false);
3491 return GET_PRIVATE(acc)->has_stock_split;
3499 GetBalanceAsOfDate (
Account *acc,
time64 date, std::function<gnc_numeric(Split*)> split_to_numeric)
3501 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3506 auto is_before_date = [date](
auto s) ->
bool 3510 return latest_split ? split_to_numeric (latest_split) : gnc_numeric_zero();
3520 xaccAccountGetNoclosingBalanceAsOfDate (
Account *acc,
time64 date)
3535 xaccAccountGetPresentBalance (
const Account *acc)
3537 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3554 xaccAccountConvertBalanceToCurrency(
const Account *acc,
3555 gnc_numeric balance,
3556 const gnc_commodity *balance_currency,
3557 const gnc_commodity *new_currency)
3566 book = gnc_account_get_book (acc);
3570 pdb, balance, balance_currency, new_currency);
3580 xaccAccountConvertBalanceToCurrencyAsOfDate(
const Account *acc,
3581 gnc_numeric balance,
3582 const gnc_commodity *balance_currency,
3583 const gnc_commodity *new_currency,
3593 book = gnc_account_get_book (acc);
3597 pdb, balance, balance_currency, new_currency, date);
3608 xaccAccountGetXxxBalanceInCurrency (
const Account *acc,
3609 xaccGetBalanceFn fn,
3610 const gnc_commodity *report_currency)
3613 gnc_numeric balance;
3615 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), gnc_numeric_zero());
3616 g_return_val_if_fail(fn, gnc_numeric_zero());
3617 g_return_val_if_fail(GNC_IS_COMMODITY(report_currency), gnc_numeric_zero());
3619 priv = GET_PRIVATE(acc);
3621 balance = xaccAccountConvertBalanceToCurrency(acc, balance,
3628 xaccAccountGetXxxBalanceAsOfDateInCurrency(
Account *acc,
time64 date,
3629 xaccGetBalanceAsOfDateFn fn,
3630 const gnc_commodity *report_commodity)
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_commodity), gnc_numeric_zero());
3638 priv = GET_PRIVATE(acc);
3639 return xaccAccountConvertBalanceToCurrencyAsOfDate(
3640 acc, fn(acc, date), priv->commodity, report_commodity, date);
3648 const gnc_commodity *currency;
3649 gnc_numeric balance;
3650 xaccGetBalanceFn fn;
3651 xaccGetBalanceAsOfDateFn asOfDateFn;
3662 xaccAccountBalanceHelper (
Account *acc, gpointer data)
3665 gnc_numeric balance;
3667 if (!cb->fn || !cb->currency)
3669 balance = xaccAccountGetXxxBalanceInCurrency (acc, cb->fn, cb->currency);
3676 xaccAccountBalanceAsOfDateHelper (
Account *acc, gpointer data)
3679 gnc_numeric balance;
3681 g_return_if_fail (cb->asOfDateFn && cb->currency);
3683 balance = xaccAccountGetXxxBalanceAsOfDateInCurrency (
3684 acc, cb->date, cb->asOfDateFn, cb->currency);
3703 xaccAccountGetXxxBalanceInCurrencyRecursive (
const Account *acc,
3704 xaccGetBalanceFn fn,
3705 const gnc_commodity *report_commodity,
3706 gboolean include_children)
3708 gnc_numeric balance;
3710 if (!acc)
return gnc_numeric_zero ();
3711 if (!report_commodity)
3713 if (!report_commodity)
3714 return gnc_numeric_zero();
3716 balance = xaccAccountGetXxxBalanceInCurrency (acc, fn, report_commodity);
3720 if (include_children)
3727 cb.balance = balance;
3733 balance = cb.balance;
3740 xaccAccountGetXxxBalanceAsOfDateInCurrencyRecursive (
3742 const gnc_commodity *report_commodity, gboolean include_children)
3744 gnc_numeric balance;
3746 g_return_val_if_fail(acc, gnc_numeric_zero());
3747 if (!report_commodity)
3749 if (!report_commodity)
3750 return gnc_numeric_zero();
3752 balance = xaccAccountGetXxxBalanceAsOfDateInCurrency(
3753 acc, date, fn, report_commodity);
3757 if (include_children)
3764 cb.balance = balance;
3766 CurrencyBalance cb = { report_commodity, balance,
nullptr, fn, date };
3770 balance = cb.balance;
3777 xaccAccountGetBalanceInCurrency (
const Account *acc,
3778 const gnc_commodity *report_commodity,
3779 gboolean include_children)
3782 rc = xaccAccountGetXxxBalanceInCurrencyRecursive (
3784 PINFO(
" baln=%" G_GINT64_FORMAT
"/%" G_GINT64_FORMAT, rc.num, rc.denom);
3790 xaccAccountGetClearedBalanceInCurrency (
const Account *acc,
3791 const gnc_commodity *report_commodity,
3792 gboolean include_children)
3794 return xaccAccountGetXxxBalanceInCurrencyRecursive (
3800 xaccAccountGetReconciledBalanceInCurrency (
const Account *acc,
3801 const gnc_commodity *report_commodity,
3802 gboolean include_children)
3804 return xaccAccountGetXxxBalanceInCurrencyRecursive (
3810 xaccAccountGetPresentBalanceInCurrency (
const Account *acc,
3811 const gnc_commodity *report_commodity,
3812 gboolean include_children)
3814 return xaccAccountGetXxxBalanceAsOfDateInCurrencyRecursive (
3821 xaccAccountGetProjectedMinimumBalanceInCurrency (
3823 const gnc_commodity *report_commodity,
3824 gboolean include_children)
3826 return xaccAccountGetXxxBalanceInCurrencyRecursive (
3827 acc, xaccAccountGetProjectedMinimumBalance, report_commodity,
3834 gboolean include_children)
3836 return xaccAccountGetXxxBalanceAsOfDateInCurrencyRecursive (
3844 gboolean include_children)
3846 return xaccAccountGetXxxBalanceAsOfDateInCurrencyRecursive
3847 (acc, date, xaccAccountGetNoclosingBalanceAsOfDate,
3848 report_commodity, include_children);
3863 xaccAccountGetNoclosingBalanceChangeForPeriod (
Account *acc,
time64 t1,
3864 time64 t2, gboolean recurse)
3875 const gnc_commodity *currency;
3876 gnc_numeric balanceChange;
3882 xaccAccountBalanceChangeHelper (
Account *acc, gpointer data)
3890 gnc_numeric balanceChange_conv = xaccAccountConvertBalanceToCurrencyAsOfDate(acc, balanceChange,
xaccAccountGetCommodity(acc), cbdiff->currency, cbdiff->t2);
3891 cbdiff->balanceChange =
gnc_numeric_add (cbdiff->balanceChange, balanceChange_conv,
3897 xaccAccountGetNoclosingBalanceChangeInCurrencyForPeriod (
Account *acc,
time64 t1,
3898 time64 t2, gboolean recurse)
3913 balanceChange = cbdiff.balanceChange;
3915 return balanceChange;
3922 xaccAccountGetSplits (
const Account *account)
3924 static const SplitsVec empty;
3925 g_return_val_if_fail (GNC_IS_ACCOUNT(account), empty);
3926 return GET_PRIVATE(account)->splits;
3932 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3933 auto priv{GET_PRIVATE(acc)};
3934 return std::accumulate (priv->splits.rbegin(), priv->splits.rend(),
3935 static_cast<GList*
>(
nullptr), g_list_prepend);
3939 xaccAccountGetSplitsSize (
const Account *account)
3941 g_return_val_if_fail (GNC_IS_ACCOUNT(account), 0);
3942 return GNC_IS_ACCOUNT(account) ? GET_PRIVATE(account)->splits.size() : 0;
3946 gnc_account_and_descendants_empty (
Account *acc)
3948 g_return_val_if_fail (GNC_IS_ACCOUNT (acc), FALSE);
3949 auto priv = GET_PRIVATE (acc);
3950 if (!priv->splits.empty())
return FALSE;
3951 return std::all_of (priv->children.begin(), priv->children.end(),
3952 gnc_account_and_descendants_empty);
3958 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3959 return g_list_copy(GET_PRIVATE(acc)->lots);
3964 gboolean (*match_func)(GNCLot *lot,
3965 gpointer user_data),
3966 gpointer user_data, GCompareFunc sort_func)
3970 GList *retval =
nullptr;
3972 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
3974 priv = GET_PRIVATE(acc);
3975 for (lot_list = priv->lots; lot_list; lot_list = lot_list->next)
3977 GNCLot *lot =
static_cast<GNCLot*
>(lot_list->data);
3983 if (match_func && !(match_func)(lot, user_data))
3987 retval = g_list_prepend (retval, lot);
3991 retval = g_list_sort (retval, sort_func);
3998 gpointer (*proc)(GNCLot *lot,
void *data),
void *data)
4000 g_return_val_if_fail(GNC_IS_ACCOUNT(acc),
nullptr);
4001 g_return_val_if_fail(proc,
nullptr);
4003 for (
auto node = GET_PRIVATE(acc)->lots; node; node = node->next)
4004 if (
auto result = proc(GNC_LOT(node->data), data))
4018 return get_kvp_boolean_path(acc, {
"tax-related"});
4024 set_kvp_boolean_path(acc, {
"tax-related"}, tax_related);
4030 return get_kvp_string_path (acc, {
"tax-US",
"code"});
4036 set_kvp_string_path (acc, {
"tax-US",
"code"}, code);
4042 return get_kvp_string_path (acc, {
"tax-US",
"payer-name-source"});
4048 set_kvp_string_path (acc, {
"tax-US",
"payer-name-source"}, source);
4054 auto copy_number = get_kvp_int64_path (acc, {
"tax-US",
"copy-number"});
4055 return (copy_number && (*copy_number != 0)) ? *copy_number : 1;
4061 if (copy_number != 0)
4062 set_kvp_int64_path (acc, {
"tax-US",
"copy-number"}, copy_number);
4065 set_kvp_int64_path (acc, {
"tax-US",
"copy-number"}, std::nullopt);
4075 return _(dflt_acct_debit_str);
4077 auto result = gnc_acct_debit_strs.find(acct_type);
4078 if (result != gnc_acct_debit_strs.end())
4079 return _(result->second);
4081 return _(dflt_acct_debit_str);
4087 return _(dflt_acct_credit_str);
4089 auto result = gnc_acct_credit_strs.find(acct_type);
4090 if (result != gnc_acct_credit_strs.end())
4091 return _(result->second);
4093 return _(dflt_acct_credit_str);
4102 return get_kvp_boolean_path(acc, {
"placeholder"});
4108 set_kvp_boolean_path(acc, {
"placeholder"}, val);
4114 return get_kvp_boolean_path(acc, {
"import-append-text"});
4120 set_kvp_boolean_path(acc, {
"import-append-text"}, val);
4126 g_return_val_if_fail (GNC_IS_ACCOUNT(acc),
false);
4130 return !g_strcmp0 (get_kvp_string_path (acc, {
"equity-type"}),
"opening-balance");
4136 g_return_if_fail (GNC_IS_ACCOUNT(acc));
4139 set_kvp_string_path(acc, {
"equity-type"}, val ?
"opening-balance" :
nullptr);
4145 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), PLACEHOLDER_NONE);
4149 ? PLACEHOLDER_CHILD : PLACEHOLDER_NONE;
4158 return get_kvp_boolean_path (acc, {KEY_RECONCILE_INFO,
"auto-interest-transfer"});
4164 set_kvp_boolean_path (acc, {KEY_RECONCILE_INFO,
"auto-interest-transfer"}, val);
4173 return get_kvp_boolean_path (acc, {
"hidden"});
4179 set_kvp_boolean_path (acc, {
"hidden"}, val);
4187 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4191 priv = GET_PRIVATE(acc);
4192 while ((acc = priv->parent) !=
nullptr)
4194 priv = GET_PRIVATE(acc);
4209 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4210 g_return_val_if_fail(GNC_IS_ACCOUNT(ancestor), FALSE);
4213 while (parent && parent != ancestor)
4214 parent = GET_PRIVATE(parent)->parent;
4216 return (parent == ancestor);
4225 #define GNC_RETURN_ENUM_AS_STRING(x) case (ACCT_TYPE_ ## x): return #x; 4232 GNC_RETURN_ENUM_AS_STRING(NONE);
4233 GNC_RETURN_ENUM_AS_STRING(BANK);
4234 GNC_RETURN_ENUM_AS_STRING(CASH);
4235 GNC_RETURN_ENUM_AS_STRING(CREDIT);
4236 GNC_RETURN_ENUM_AS_STRING(ASSET);
4237 GNC_RETURN_ENUM_AS_STRING(LIABILITY);
4238 GNC_RETURN_ENUM_AS_STRING(STOCK);
4239 GNC_RETURN_ENUM_AS_STRING(MUTUAL);
4240 GNC_RETURN_ENUM_AS_STRING(CURRENCY);
4241 GNC_RETURN_ENUM_AS_STRING(INCOME);
4242 GNC_RETURN_ENUM_AS_STRING(EXPENSE);
4243 GNC_RETURN_ENUM_AS_STRING(EQUITY);
4244 GNC_RETURN_ENUM_AS_STRING(RECEIVABLE);
4245 GNC_RETURN_ENUM_AS_STRING(PAYABLE);
4246 GNC_RETURN_ENUM_AS_STRING(ROOT);
4247 GNC_RETURN_ENUM_AS_STRING(TRADING);
4248 GNC_RETURN_ENUM_AS_STRING(CHECKING);
4249 GNC_RETURN_ENUM_AS_STRING(SAVINGS);
4250 GNC_RETURN_ENUM_AS_STRING(MONEYMRKT);
4251 GNC_RETURN_ENUM_AS_STRING(CREDITLINE);
4253 PERR (
"asked to translate unknown account type %d.\n", type);
4259 #undef GNC_RETURN_ENUM_AS_STRING 4261 #define GNC_RETURN_ON_MATCH(x) \ 4262 if(g_strcmp0(#x, (str)) == 0) { *type = ACCT_TYPE_ ## x; return(TRUE); } 4268 GNC_RETURN_ON_MATCH(NONE);
4269 GNC_RETURN_ON_MATCH(BANK);
4270 GNC_RETURN_ON_MATCH(CASH);
4271 GNC_RETURN_ON_MATCH(CREDIT);
4272 GNC_RETURN_ON_MATCH(ASSET);
4273 GNC_RETURN_ON_MATCH(LIABILITY);
4274 GNC_RETURN_ON_MATCH(STOCK);
4275 GNC_RETURN_ON_MATCH(MUTUAL);
4276 GNC_RETURN_ON_MATCH(CURRENCY);
4277 GNC_RETURN_ON_MATCH(INCOME);
4278 GNC_RETURN_ON_MATCH(EXPENSE);
4279 GNC_RETURN_ON_MATCH(EQUITY);
4280 GNC_RETURN_ON_MATCH(RECEIVABLE);
4281 GNC_RETURN_ON_MATCH(PAYABLE);
4282 GNC_RETURN_ON_MATCH(ROOT);
4283 GNC_RETURN_ON_MATCH(TRADING);
4284 GNC_RETURN_ON_MATCH(CHECKING);
4285 GNC_RETURN_ON_MATCH(SAVINGS);
4286 GNC_RETURN_ON_MATCH(MONEYMRKT);
4287 GNC_RETURN_ON_MATCH(CREDITLINE);
4289 PERR(
"asked to translate unknown account type string %s.\n",
4290 str ? str :
"(null)");
4295 #undef GNC_RETURN_ON_MATCH 4341 return _(account_type_name [type]);
4383 PERR(
"bad account type: %d", type);
4429 PERR(
"bad account type: %d", type);
4536 g_return_val_if_fail(GNC_IS_ACCOUNT(acc), FALSE);
4538 priv = GET_PRIVATE(acc);
4549 gboolean retval = FALSE;
4550 auto date = get_kvp_int64_path (acc, {KEY_RECONCILE_INFO,
"last-date"});
4567 set_kvp_int64_path (acc, {KEY_RECONCILE_INFO,
"last-date"}, last_date);
4575 int *months,
int *days)
4577 if (!acc)
return FALSE;
4578 auto m{get_kvp_int64_path (acc, {KEY_RECONCILE_INFO,
"last-interval",
"months"})};
4579 auto d{get_kvp_int64_path (acc, {KEY_RECONCILE_INFO,
"last-interval",
"days"})};
4597 set_kvp_int64_path (acc, {KEY_RECONCILE_INFO,
"last-interval",
"months"}, months);
4598 set_kvp_int64_path (acc, {KEY_RECONCILE_INFO,
"last-interval",
"days"}, days);
4607 if (
auto date = get_kvp_int64_path (acc, {KEY_RECONCILE_INFO, KEY_POSTPONE,
"date"}))
4610 *postpone_date = *date;
4622 set_kvp_int64_path (acc, {KEY_RECONCILE_INFO, KEY_POSTPONE,
"date"}, postpone_date);
4630 gnc_numeric *balance)
4632 if (
auto bal = get_kvp_gnc_numeric_path (acc, {KEY_RECONCILE_INFO, KEY_POSTPONE,
"balance"}))
4647 set_kvp_gnc_numeric_path (acc, {KEY_RECONCILE_INFO, KEY_POSTPONE,
"balance"}, balance);
4657 set_kvp_gnc_numeric_path (acc, {KEY_RECONCILE_INFO, KEY_POSTPONE}, {});
4666 return get_kvp_string_path (acc, {
"last-num"});
4675 set_kvp_string_path (acc, {
"last-num"}, num);
4683 get_balance_limit (
const Account* acc,
const std::string& key, gnc_numeric* balance)
4685 auto limit = get_kvp_gnc_numeric_path (acc, {KEY_BALANCE_LIMIT, key});
4687 *balance = gnc_numeric_create (limit->num, limit->denom);
4688 return limit.has_value();
4692 set_balance_limit (
Account *acc,
const std::string& key, std::optional<gnc_numeric> balance)
4696 set_kvp_gnc_numeric_path (acc, {KEY_BALANCE_LIMIT, key}, balance);
4701 gnc_numeric *balance)
4703 return get_balance_limit (acc, KEY_BALANCE_HIGHER_LIMIT_VALUE, balance);
4708 gnc_numeric *balance)
4710 return get_balance_limit (acc, KEY_BALANCE_LOWER_LIMIT_VALUE, balance);
4716 set_balance_limit (acc, KEY_BALANCE_HIGHER_LIMIT_VALUE, balance);
4722 set_balance_limit (acc, KEY_BALANCE_LOWER_LIMIT_VALUE, balance);
4728 set_balance_limit (acc, KEY_BALANCE_HIGHER_LIMIT_VALUE, {});
4734 set_balance_limit (acc, KEY_BALANCE_LOWER_LIMIT_VALUE, {});
4740 return get_kvp_boolean_path (acc, {KEY_BALANCE_LIMIT, KEY_BALANCE_INCLUDE_SUB_ACCTS});
4746 set_kvp_boolean_path (acc, {KEY_BALANCE_LIMIT, KEY_BALANCE_INCLUDE_SUB_ACCTS}, inc_sub);
4753 GetOrMakeOrphanAccount (
Account *root, gnc_commodity * currency)
4758 g_return_val_if_fail (root,
nullptr);
4763 PERR (
"No currency specified!");
4767 accname = g_strconcat (_(
"Orphaned Gains"),
"-",
4783 _(
"Realized Gains or Losses from " 4784 "Commodity or Trading Accounts " 4785 "that haven't been recorded elsewhere."));
4801 auto gains_account = get_kvp_account_path (acc, path);
4803 if (gains_account ==
nullptr)
4806 set_kvp_account_path (acc, path, gains_account);
4809 return gains_account;
4821 set_kvp_string_path (acc, {
"old-price-source"}, src);
4830 if (!acc)
return nullptr;
4834 return get_kvp_string_path (acc, {
"old-price-source"});
4845 set_kvp_string_path (acc, {
"old-quote-tz"}, tz);
4854 if (!acc)
return nullptr;
4856 return get_kvp_string_path (acc, {
"old-quote-tz"});
4869 set_kvp_int64_path (acc, {KEY_RECONCILE_INFO, KEY_INCLUDE_CHILDREN}, status);
4882 return get_kvp_boolean_path (acc, {KEY_RECONCILE_INFO, KEY_INCLUDE_CHILDREN});
4891 auto has_description = [description](
const Split* s) ->
bool 4916 g_return_if_fail(GNC_IS_ACCOUNT(to_parent));
4917 g_return_if_fail(GNC_IS_ACCOUNT(from_parent));
4920 auto from_priv = GET_PRIVATE(from_parent);
4921 if (from_priv->children.empty())
4925 auto children = from_priv->children;
4926 for (
auto child : children)
4936 g_return_if_fail(GNC_IS_ACCOUNT(parent));
4938 auto ppriv = GET_PRIVATE(parent);
4939 for (
auto it_a = ppriv->children.begin(); it_a != ppriv->children.end(); it_a++)
4942 auto priv_a = GET_PRIVATE(acc_a);
4943 for (
auto it_b = std::next(it_a); it_b != ppriv->children.end(); it_b++)
4946 auto priv_b = GET_PRIVATE(acc_b);
4947 if (0 !=
null_strcmp(priv_a->accountName, priv_b->accountName))
4949 if (0 !=
null_strcmp(priv_a->accountCode, priv_b->accountCode))
4951 if (0 !=
null_strcmp(priv_a->description, priv_b->description))
4961 if (priv_a->type != priv_b->type)
4965 if (!priv_b->children.empty())
4967 auto work = priv_b->children;
4979 while (!priv_b->splits.empty())
4980 xaccSplitSetAccount (priv_b->splits.front(), acc_a);
4999 xaccSplitsBeginStagedTransactionTraversals (SplitsVec& splits)
5001 for (
auto s : splits)
5003 Transaction *trans = s->parent;
5016 xaccSplitsBeginStagedTransactionTraversals(GET_PRIVATE (account)->splits);
5022 if (trans ==
nullptr)
return FALSE;
5024 if (trans->marker < stage)
5026 trans->marker = stage;
5037 auto do_one_account = [](
auto acc)
5038 { gnc_account_foreach_split (acc, [](
auto s){ s->parent->marker = 0; }); };
5045 TransactionCallback thunk,
5051 auto splits = GET_PRIVATE(acc)->splits;
5052 for (
auto s : splits)
5054 auto trans = s->parent;
5055 if (trans && (trans->marker < stage))
5057 trans->marker = stage;
5060 auto retval = thunk(trans, cb_data);
5061 if (retval)
return retval;
5072 TransactionCallback thunk,
5082 priv = GET_PRIVATE(acc);
5083 for (
auto acc_p : priv->children)
5086 if (retval)
return retval;
5090 for (
auto s : priv->splits)
5093 if (trans && (trans->marker < stage))
5095 trans->marker = stage;
5098 retval = thunk(trans, cb_data);
5099 if (retval)
return retval;
5110 g_return_val_if_fail (GNC_IS_ACCOUNT(account), INT64_MAX);
5111 const auto& splits = xaccAccountGetSplits (account);
5120 int (*proc)(Transaction *t,
void *data),
5123 if (!acc || !proc)
return 0;
5134 if (!acc || !proc)
return 0;
5145 #define IMAP_FRAME "import-map" 5146 #define IMAP_FRAME_BAYES "import-map-bayes" 5150 gnc_account_imap_find_account (
Account *acc,
5151 const char *category,
5154 if (!acc || !key)
return nullptr;
5155 std::vector<std::string> path {IMAP_FRAME};
5157 path.push_back (category);
5158 path.push_back (key);
5159 return get_kvp_account_path (acc, path);
5163 gnc_account_imap_find_any (
QofBook *book,
const char* category,
const char *key)
5168 auto root = gnc_book_get_root_account (book);
5172 for (
auto ptr = accts; ptr; ptr = g_list_next (ptr))
5174 auto tmp_acc =
static_cast<Account*
> (ptr->data);
5176 if (gnc_account_imap_find_account (tmp_acc, category, key))
5182 g_list_free (accts);
5189 gnc_account_imap_add_account (
Account *acc,
5190 const char *category,
5194 if (!acc || !key || !added_acc || !*key)
return;
5196 auto path = category ? Path{IMAP_FRAME, category, key} : Path{IMAP_FRAME, key};
5198 set_kvp_account_path (acc, path, added_acc);
5203 gnc_account_imap_delete_account (
Account *acc,
5204 const char *category,
5207 if (!acc || !key)
return;
5209 auto path = category ? Path{IMAP_FRAME, category, key} : Path{IMAP_FRAME, key};
5210 if (qof_instance_has_path_slot (QOF_INSTANCE (acc), path))
5212 qof_instance_slot_path_delete (QOF_INSTANCE (acc), path);
5214 qof_instance_slot_path_delete_if_empty (QOF_INSTANCE (acc), {IMAP_FRAME, category});
5215 qof_instance_slot_path_delete_if_empty (QOF_INSTANCE (acc), {IMAP_FRAME});
5217 qof_instance_set_dirty (QOF_INSTANCE (acc));
5232 double product_difference;
5237 std::string account_guid;
5238 int64_t token_count;
5246 std::vector<AccountTokenCount> accounts;
5247 int64_t total_count;
5255 std::string account_guid;
5256 int32_t probability;
5260 build_token_info(
char const * suffix, KvpValue * value,
TokenAccountsInfo & tokenInfo)
5264 tokenInfo.total_count += value->get<int64_t>();
5266 tokenInfo.accounts.emplace_back(
AccountTokenCount{std::string{suffix}, value->get<int64_t>()});
5273 static constexpr
int probability_factor = 100000;
5275 static FinalProbabilityVec
5276 build_probabilities(ProbabilityVec
const & first_pass)
5278 FinalProbabilityVec ret;
5279 for (
auto const & first_pass_prob : first_pass)
5281 auto const & account_probability = first_pass_prob.second;
5286 int32_t probability = (account_probability.product /
5287 (account_probability.product + account_probability.product_difference)) * probability_factor;
5288 ret.push_back({first_pass_prob.first, probability});
5294 highest_probability(FinalProbabilityVec
const & probabilities)
5296 AccountInfo ret {
"", std::numeric_limits<int32_t>::min()};
5297 for (
auto const & prob : probabilities)
5298 if (prob.second > ret.probability)
5303 static ProbabilityVec
5304 get_first_pass_probabilities(
Account* acc, GList * tokens)
5309 for (
auto current_token = tokens; current_token; current_token = current_token->next)
5312 auto path = std::string{IMAP_FRAME_BAYES
"/"} + static_cast <
char const *> (current_token->data) +
"/";
5313 qof_instance_foreach_slot_prefix (QOF_INSTANCE (acc), path, &build_token_info, tokenInfo);
5314 for (
auto const & current_account_token : tokenInfo.accounts)
5316 auto item = std::find_if(ret.begin(), ret.end(), [¤t_account_token]
5317 (std::pair<std::string, AccountProbability>
const & a) {
5318 return current_account_token.account_guid == a.first;
5320 if (item != ret.end())
5322 item->second.product = ((double)current_account_token.token_count /
5323 (
double)tokenInfo.total_count) * item->second.product;
5324 item->second.product_difference = ((
double)1 - ((double)current_account_token.token_count /
5325 (
double)tokenInfo.total_count)) * item->second.product_difference;
5331 new_probability.product = ((double)current_account_token.token_count /
5332 (
double)tokenInfo.total_count);
5333 new_probability.product_difference = 1 - (new_probability.product);
5334 ret.push_back({current_account_token.account_guid, std::move(new_probability)});
5342 look_for_old_separator_descendants (
Account *root, std::string
const & full_name,
const gchar *separator)
5344 GList *top_accounts, *ptr;
5348 PINFO(
"Incoming full_name is '%s', current separator is '%s'", full_name.c_str (), separator);
5350 for (ptr = top_accounts; ptr; ptr = g_list_next (ptr))
5354 if (g_str_has_prefix (full_name.c_str (), name))
5356 gint name_len = strlen (name);
5357 const gchar old_sep = full_name[name_len];
5358 if (!g_ascii_isalnum (old_sep))
5360 if (name_len > found_len)
5362 found_sep = full_name[name_len];
5363 found_len = name_len;
5368 g_list_free (top_accounts);
5369 std::string new_name {full_name};
5371 std::replace (new_name.begin (), new_name.end (), found_sep, *separator);
5372 PINFO (
"Return full_name is '%s'", new_name.c_str ());
5377 get_guid_from_account_name (
Account * root, std::string
const & name)
5382 auto temp_account_name = look_for_old_separator_descendants (root, name,
5387 return temp_guid.to_string ();
5391 convert_entry (KvpEntry entry,
Account* root)
5394 auto account_name = entry.first.back();
5395 if (!gnc::GUID::is_valid_guid (account_name))
5401 entry.first.pop_back();
5402 auto guid_str = get_guid_from_account_name (root, account_name);
5403 entry.first.emplace_back (guid_str);
5405 std::string new_key {std::accumulate (entry.first.begin(), entry.first.end(), std::string {})};
5406 new_key = IMAP_FRAME_BAYES + new_key;
5407 return {new_key, entry.second};
5410 static std::vector<FlatKvpEntry>
5413 auto frame = qof_instance_get_slots (QOF_INSTANCE (acc));
5414 auto slot = frame->get_slot ({IMAP_FRAME_BAYES});
5417 auto imap_frame = slot->get<KvpFrame*> ();
5418 auto flat_kvp = imap_frame->flatten_kvp ();
5420 std::vector <FlatKvpEntry> ret;
5421 for (
auto const & flat_entry : flat_kvp)
5423 auto converted_entry = convert_entry (flat_entry, root);
5425 if (converted_entry.first.size())
5426 ret.emplace_back (converted_entry);
5432 convert_imap_account_bayes_to_flat (
Account *acc)
5434 auto frame = qof_instance_get_slots (QOF_INSTANCE (acc));
5435 if (!frame->get_keys().size())
5437 auto flat_imap = get_flat_imap(acc);
5438 if (!flat_imap.size ())
5441 frame->set({IMAP_FRAME_BAYES},
nullptr);
5442 std::for_each(flat_imap.begin(), flat_imap.end(),
5443 [&frame] (FlatKvpEntry
const & entry) {
5444 frame->set({entry.first.c_str()}, entry.second);
5446 qof_instance_set_dirty (QOF_INSTANCE (acc));
5455 imap_convert_bayes_to_flat (
QofBook * book)
5457 auto root = gnc_book_get_root_account (book);
5460 for (
auto ptr = accts; ptr; ptr = g_list_next (ptr))
5463 if (convert_imap_account_bayes_to_flat (acc))
5469 g_list_free (accts);
5476 imap_convert_bayes_to_flat_run =
false;
5491 check_import_map_data (
QofBook *book)
5493 if (gnc_features_check_used (book, GNC_FEATURE_GUID_FLAT_BAYESIAN) ||
5494 imap_convert_bayes_to_flat_run)
5498 imap_convert_bayes_to_flat (book);
5499 imap_convert_bayes_to_flat_run =
true;
5502 static constexpr
double threshold = .90 * probability_factor;
5510 auto book = gnc_account_get_book(acc);
5511 check_import_map_data (book);
5512 auto first_pass = get_first_pass_probabilities(acc, tokens);
5513 if (!first_pass.size())
5515 auto final_probabilities = build_probabilities(first_pass);
5516 if (!final_probabilities.size())
5518 auto best = highest_probability(final_probabilities);
5519 if (best.account_guid ==
"")
5521 if (best.probability < threshold)
5525 guid = gnc::GUID::from_string(best.account_guid);
5534 change_imap_entry (
Account *acc, std::string
const & path, int64_t token_count)
5536 PINFO(
"Source Account is '%s', Count is '%" G_GINT64_FORMAT
"'",
5540 if (
auto existing_token_count = get_kvp_int64_path (acc, {path}))
5542 PINFO(
"found existing value of '%" G_GINT64_FORMAT
"'", *existing_token_count);
5543 token_count += *existing_token_count;
5547 set_kvp_int64_path (acc, {path}, token_count);
5556 GList *current_token;
5558 char *account_fullname;
5567 check_import_map_data (gnc_account_get_book(acc));
5569 g_return_if_fail (added_acc !=
nullptr);
5573 PINFO(
"account name: '%s'", account_fullname);
5578 for (current_token = g_list_first(tokens); current_token;
5579 current_token = current_token->next)
5581 char* token =
static_cast<char*
>(current_token->data);
5586 if (!token || !token[0])
5590 PINFO(
"adding token '%s'", token);
5591 auto path = std::string {IMAP_FRAME_BAYES} +
'/' + token +
'/' + guid_string;
5593 change_imap_entry (acc, path, token_count);
5598 g_free (account_fullname);
5599 g_free (guid_string);
5606 build_non_bayes (
const char *key,
const GValue *value, gpointer user_data)
5608 if (!G_VALUE_HOLDS_BOXED (value))
5612 gchar *guid_string =
nullptr;
5617 guid = (
GncGUID*)g_value_get_boxed (value);
5620 PINFO(
"build_non_bayes: match string '%s', match account guid: '%s'",
5621 (
char*)key, guid_string);
5625 imapInfo_node->source_account = imapInfo->source_account;
5627 imapInfo_node->head = g_strdup (imapInfo->head);
5628 imapInfo_node->match_string = g_strdup (key);
5629 imapInfo_node->category = g_strdup (imapInfo->category);
5630 imapInfo_node->count = g_strdup (
" ");
5632 imapInfo->list = g_list_prepend (imapInfo->list, imapInfo_node);
5634 g_free (guid_string);
5638 build_bayes (
const char *suffix, KvpValue * value,
GncImapInfo & imapInfo)
5641 std::string account_guid {&suffix[guid_start]};
5645 guid = gnc::GUID::from_string (account_guid);
5649 PWARN(
"Invalid GUID string from %s%s", IMAP_FRAME_BAYES, suffix);
5651 auto map_account =
xaccAccountLookup (&guid, gnc_account_get_book (imapInfo.source_account));
5653 auto count = value->get <int64_t> ();
5654 imap_node->source_account = imapInfo.source_account;
5655 imap_node->map_account = map_account;
5656 imap_node->head = g_strdup_printf (
"%s%s", IMAP_FRAME_BAYES, suffix);
5657 imap_node->match_string = g_strndup (&suffix[1], guid_start - 2);
5658 imap_node->category = g_strdup(
" ");
5659 imap_node->count = g_strdup_printf (
"%" G_GINT64_FORMAT, count);
5660 imapInfo.list = g_list_prepend (imapInfo.list, imap_node);
5665 g_free (imapInfo->head);
5666 g_free (imapInfo->category);
5667 g_free (imapInfo->match_string);
5668 g_free (imapInfo->count);
5675 check_import_map_data (gnc_account_get_book (acc));
5679 qof_instance_foreach_slot_prefix (QOF_INSTANCE (acc), IMAP_FRAME_BAYES, &build_bayes, imapInfo);
5680 return g_list_reverse(imapInfo.list);
5686 GList *list =
nullptr;
5690 std::vector<std::string> path {IMAP_FRAME};
5692 path.emplace_back (category);
5694 imapInfo.source_account = acc;
5695 imapInfo.list = list;
5697 imapInfo.head = g_strdup (IMAP_FRAME);
5698 imapInfo.category = g_strdup (category);
5700 if (qof_instance_has_path_slot (QOF_INSTANCE (acc), path))
5702 qof_instance_foreach_slot (QOF_INSTANCE(acc), IMAP_FRAME, category,
5703 build_non_bayes, &imapInfo);
5705 g_free (imapInfo.head);
5706 g_free (imapInfo.category);
5707 return g_list_reverse(imapInfo.list);
5715 return g_strdup (category ?
5716 get_kvp_string_path (acc, {head, category}) :
5717 get_kvp_string_path (acc, {head}));
5724 get_kvp_guid_path (acc, {head, category}) :
5725 get_kvp_guid_path (acc, {head});
5730 char *match_string, gboolean empty)
5734 std::vector<std::string> path {head};
5736 path.emplace_back (category);
5738 path.emplace_back (match_string);
5740 if (qof_instance_has_path_slot (QOF_INSTANCE (acc), path))
5744 qof_instance_slot_path_delete_if_empty (QOF_INSTANCE(acc), path);
5746 qof_instance_slot_path_delete (QOF_INSTANCE(acc), path);
5747 PINFO(
"Account is '%s', head is '%s', category is '%s', match_string is'%s'",
5749 qof_instance_set_dirty (QOF_INSTANCE(acc));
5760 auto slots = qof_instance_get_slots_prefix (QOF_INSTANCE (acc), IMAP_FRAME_BAYES);
5761 if (!slots.size())
return;
5763 for (
auto const & entry : slots)
5765 qof_instance_slot_path_delete (QOF_INSTANCE (acc), {entry.first});
5767 qof_instance_set_dirty (QOF_INSTANCE(acc));
5776 destroy_all_child_accounts (
Account *acc, gpointer data)
5783 gnc_account_book_end(
QofBook* book)
5785 Account *root_account = gnc_book_get_root_account (book);
5795 accounts = g_list_reverse (accounts);
5796 g_list_foreach (accounts, (GFunc)destroy_all_child_accounts,
nullptr);
5797 g_list_free (accounts);
5810 static QofObject account_object_def =
5813 DI(.e_type = ) GNC_ID_ACCOUNT,
5816 DI(.book_begin = )
nullptr,
5817 DI(.book_end = ) gnc_account_book_end,
5820 DI(.foreach = ) qof_collection_foreach,
5825 gboolean xaccAccountRegister (
void)
5827 static QofParam params[] =
5830 ACCOUNT_NAME_, QOF_TYPE_STRING,
5835 ACCOUNT_CODE_, QOF_TYPE_STRING,
5840 ACCOUNT_DESCRIPTION_, QOF_TYPE_STRING,
5845 ACCOUNT_COLOR_, QOF_TYPE_STRING,
5850 ACCOUNT_FILTER_, QOF_TYPE_STRING,
5855 ACCOUNT_SORT_ORDER_, QOF_TYPE_STRING,
5860 ACCOUNT_SORT_REVERSED_, QOF_TYPE_BOOLEAN,
5865 ACCOUNT_NOTES_, QOF_TYPE_STRING,
5870 ACCOUNT_PRESENT_, QOF_TYPE_NUMERIC,
5874 ACCOUNT_BALANCE_, QOF_TYPE_NUMERIC,
5878 ACCOUNT_CLEARED_, QOF_TYPE_NUMERIC,
5882 ACCOUNT_RECONCILED_, QOF_TYPE_NUMERIC,
5886 ACCOUNT_TYPE_, QOF_TYPE_STRING,
5891 ACCOUNT_FUTURE_MINIMUM_, QOF_TYPE_NUMERIC,
5892 (
QofAccessFunc) xaccAccountGetProjectedMinimumBalance,
nullptr 5895 ACCOUNT_TAX_RELATED, QOF_TYPE_BOOLEAN,
5900 ACCOUNT_OPENING_BALANCE_, QOF_TYPE_BOOLEAN,
5905 ACCOUNT_SCU, QOF_TYPE_INT32,
5910 ACCOUNT_NSCU, QOF_TYPE_BOOLEAN,
5915 ACCOUNT_PARENT, GNC_ID_ACCOUNT,
5924 QOF_PARAM_GUID, QOF_TYPE_GUID,
5939 utest_account_get_private (
Account *acc)
5941 return GET_PRIVATE (acc);
5945 _utest_account_fill_functions(
void)
5949 func->get_private = utest_account_get_private;
5950 func->coll_get_root_account = gnc_coll_get_root_account;
5951 func->xaccFreeAccountChildren = xaccFreeAccountChildren;
5952 func->xaccFreeAccount = xaccFreeAccount;
5953 func->qofAccountSetParent = qofAccountSetParent;
5954 func->gnc_account_lookup_by_full_name_helper =
5955 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...