bool GncSqlBackend::write_account_tree(Account* root) { GList* descendants; GList* node; bool is_ok = true; g_return_val_if_fail (root != nullptr, false); auto obe = m_backend_registry.get_object_backend(GNC_ID_ACCOUNT); is_ok = obe->commit (this, QOF_INSTANCE (root)); if (is_ok) { descendants = gnc_account_get_descendants (root); for (node = descendants; node != NULL && is_ok; node = g_list_next (node)) { is_ok = obe->commit(this, QOF_INSTANCE (GNC_ACCOUNT (node->data))); if (!is_ok) break; } g_list_free (descendants); } update_progress(); return is_ok; }
/* * Given an owner, extract the open balance from the owner and then * convert it to the desired currency. */ gnc_numeric gncOwnerGetBalanceInCurrency (const GncOwner *owner, const gnc_commodity *report_currency) { gnc_numeric balance = gnc_numeric_zero (); GList *acct_list, *acct_node, *acct_types, *lot_list = NULL, *lot_node; QofBook *book; gnc_commodity *owner_currency; GNCPriceDB *pdb; g_return_val_if_fail (owner, gnc_numeric_zero ()); /* Get account list */ book = qof_instance_get_book (qofOwnerGetOwner (owner)); acct_list = gnc_account_get_descendants (gnc_book_get_root_account (book)); acct_types = gncOwnerGetAccountTypesList (owner); owner_currency = gncOwnerGetCurrency (owner); /* For each account */ for (acct_node = acct_list; acct_node; acct_node = acct_node->next) { Account *account = acct_node->data; /* Check if this account can have lots for the owner, otherwise skip to next */ if (g_list_index (acct_types, (gpointer)xaccAccountGetType (account)) == -1) continue; if (!gnc_commodity_equal (owner_currency, xaccAccountGetCommodity (account))) continue; /* Get a list of open lots for this owner and account */ lot_list = xaccAccountFindOpenLots (account, gncOwnerLotMatchOwnerFunc, (gpointer)owner, NULL); /* For each lot */ for (lot_node = lot_list; lot_node; lot_node = lot_node->next) { GNCLot *lot = lot_node->data; gnc_numeric lot_balance = gnc_lot_get_balance (lot); GncInvoice *invoice = gncInvoiceGetInvoiceFromLot(lot); if (invoice) balance = gnc_numeric_add (balance, lot_balance, gnc_commodity_get_fraction (owner_currency), GNC_HOW_RND_ROUND_HALF_UP); } } pdb = gnc_pricedb_get_db (book); if (report_currency) balance = gnc_pricedb_convert_balance_latest_price ( pdb, balance, owner_currency, report_currency); return balance; }
static void sxtg_mark_clean(QofCollection *col) { Account *root; GList *descendants; root = gnc_collection_get_template_root(col); qof_collection_mark_clean(col); descendants = gnc_account_get_descendants(root); g_list_foreach(descendants, (GFunc)qof_instance_mark_clean, NULL); g_list_free(descendants); }
static void gnc_ledger_display_make_query (GNCLedgerDisplay *ld, gint limit, SplitRegisterType type) { Account *leader; GList *accounts; if (!ld) return; switch (ld->ld_type) { case LD_SINGLE: case LD_SUBACCOUNT: break; case LD_GL: return; default: PERR ("unknown ledger type: %d", ld->ld_type); return; } qof_query_destroy (ld->query); ld->query = qof_query_create_for(GNC_ID_SPLIT); /* This is a bit of a hack. The number of splits should be * configurable, or maybe we should go back a time range instead * of picking a number, or maybe we should be able to exclude * based on reconciled status. Anyway, this works for now. */ if ((limit != 0) && (type != SEARCH_LEDGER)) qof_query_set_max_results (ld->query, limit); qof_query_set_book (ld->query, gnc_get_current_book()); leader = gnc_ledger_display_leader (ld); if (ld->ld_type == LD_SUBACCOUNT) accounts = gnc_account_get_descendants (leader); else accounts = NULL; accounts = g_list_prepend (accounts, leader); xaccQueryAddAccountMatch (ld->query, accounts, QOF_GUID_MATCH_ANY, QOF_QUERY_AND); g_list_free (accounts); }
/* Opens up a general journal window. */ GNCLedgerDisplay * gnc_ledger_display_gl (void) { Query *query; time64 start; struct tm tm; GNCLedgerDisplay *ld; ENTER(" "); query = qof_query_create_for(GNC_ID_SPLIT); qof_query_set_book (query, gnc_get_current_book()); /* In lieu of not "mis-using" some portion of the infrastructure by writing * a bunch of new code, we just filter out the accounts of the template * transactions. While these are in a seperate Account trees just for this * reason, the query engine makes no distinction between Account trees. * See Gnome Bug 86302. * -- jsled */ { Account *tRoot; GList *al; tRoot = gnc_book_get_template_root( gnc_get_current_book() ); al = gnc_account_get_descendants( tRoot ); if (g_list_length(al) != 0) xaccQueryAddAccountMatch( query, al, QOF_GUID_MATCH_NONE, QOF_QUERY_AND ); g_list_free (al); al = NULL; tRoot = NULL; } gnc_tm_get_today_start(&tm); tm.tm_mon--; /* Default the register to the last month's worth of transactions. */ start = gnc_mktime (&tm); xaccQueryAddDateMatchTT (query, TRUE, start, FALSE, 0, QOF_QUERY_AND); ld = gnc_ledger_display_internal (NULL, query, LD_GL, GENERAL_JOURNAL, REG_STYLE_JOURNAL, FALSE, FALSE); LEAVE("%p", ld); return ld; }
static gboolean sxtg_is_dirty(const QofCollection *col) { Account *root; GList *descendants, *node; gboolean dirty = FALSE; root = gnc_collection_get_template_root(col); descendants = gnc_account_get_descendants(root); for (node = descendants; node; node = g_list_next(node)) { if (qof_instance_is_dirty(node->data)) { dirty = TRUE; break; } } g_list_free(descendants); return dirty; }
/** * Saves the budget amounts for a budget. * * @param sql_be SQL backend * @param budget Budget */ static gboolean save_budget_amounts (GncSqlBackend* sql_be, GncBudget* budget) { GList* descendants; GList* node; budget_amount_info_t info; guint num_periods; gboolean is_ok = TRUE;; g_return_val_if_fail (sql_be != NULL, FALSE); g_return_val_if_fail (budget != NULL, FALSE); // Delete the amounts, then save delete_budget_amounts (sql_be, budget); info.budget = budget; num_periods = gnc_budget_get_num_periods (budget); descendants = gnc_account_get_descendants (gnc_book_get_root_account ( sql_be->book())); for (node = descendants; node != NULL && is_ok; node = g_list_next (node)) { guint i; info.account = GNC_ACCOUNT (node->data); for (i = 0; i < num_periods && is_ok; i++) { if (gnc_budget_is_account_period_value_set (budget, info.account, i)) { info.period_num = i; is_ok = sql_be->do_db_operation(OP_DB_INSERT, AMOUNTS_TABLE, "", &info, budget_amounts_col_table); } } } g_list_free (descendants); return is_ok; }
void ViewletModel::rightVGenerate(::Account *selectedAccount) { ::QofBook *book = gnc_account_get_book(selectedAccount); ::Account *rootAccount = gnc_book_get_root_account(book); GList *accountsGList = gnc_account_get_descendants(rootAccount); AccountQList accountsList = accountFromGList(accountsGList); int numOfAccounts = accountsList.count(); qDebug()<<"Total num of accounts: "<<numOfAccounts; AccountQList expenseAccountsList; for(int i = 0; i < numOfAccounts; i++) { if(xaccAccountGetType(accountsList.at(i)) == 8) { expenseAccountsList.append(accountsList.at(i)); } } SplitQList splitsList = buildSplitListDateSort(expenseAccountsList); buildMiniJournalStruct(splitsList); }
GNCSearchWindow * gnc_ui_find_transactions_dialog_create2 (GNCLedgerDisplay2 * orig_ledg) { QofIdType type = GNC_ID_SPLIT; struct _ftd_data *ftd; static GList *params = NULL; QofQuery *start_q, *show_q = NULL; gboolean num_action = qof_book_use_split_action_for_num_field(gnc_get_current_book()); /* Build parameter list in reverse order */ if (params == NULL) { params = gnc_search_param_prepend (params, N_("All Accounts"), ACCOUNT_MATCH_ALL_TYPE, type, SPLIT_TRANS, TRANS_SPLITLIST, SPLIT_ACCOUNT_GUID, NULL); params = gnc_search_param_prepend (params, N_("Account"), GNC_ID_ACCOUNT, type, SPLIT_ACCOUNT, QOF_PARAM_GUID, NULL); params = gnc_search_param_prepend (params, N_("Balanced"), NULL, type, SPLIT_TRANS, TRANS_IS_BALANCED, NULL); params = gnc_search_param_prepend (params, N_("Reconcile"), RECONCILED_MATCH_TYPE, type, SPLIT_RECONCILE, NULL); params = gnc_search_param_prepend (params, N_("Share Price"), NULL, type, SPLIT_SHARE_PRICE, NULL); params = gnc_search_param_prepend (params, N_("Shares"), NULL, type, SPLIT_AMOUNT, NULL); params = gnc_search_param_prepend (params, N_("Value"), NULL, type, SPLIT_VALUE, NULL); params = gnc_search_param_prepend (params, N_("Date Posted"), NULL, type, SPLIT_TRANS, TRANS_DATE_POSTED, NULL); params = gnc_search_param_prepend (params, N_("Notes"), NULL, type, SPLIT_TRANS, TRANS_NOTES, NULL); params = gnc_search_param_prepend (params, (num_action ? N_("Number/Action") : N_("Action")), NULL, type, SPLIT_ACTION, NULL); params = gnc_search_param_prepend (params, (num_action ? N_("Transaction Number") : N_("Number")), NULL, type, SPLIT_TRANS, TRANS_NUM, NULL); params = gnc_search_param_prepend (params, N_("Memo"), NULL, type, SPLIT_MEMO, NULL); params = gnc_search_param_prepend (params, N_("Description"), NULL, type, SPLIT_TRANS, TRANS_DESCRIPTION, NULL); } else { GList *l; for (l = params; l; l = l->next) { GNCSearchParam *param = l->data; if (num_action) { if (strcmp (param->title, N_("Action")) == 0) gnc_search_param_set_title (param, N_("Number/Action")); if (strcmp (param->title, N_("Number")) == 0) gnc_search_param_set_title (param, N_("Transaction Number")); } else { if (strcmp (param->title, N_("Number/Action")) == 0) gnc_search_param_set_title (param, N_("Action")); if (strcmp (param->title, N_("Transaction Number")) == 0) gnc_search_param_set_title (param, N_("Number")); } } } ftd = g_new0 (struct _ftd_data, 1); if (orig_ledg) { ftd->ledger_q = gnc_ledger_display2_get_query (orig_ledg); start_q = show_q = qof_query_copy (ftd->ledger_q); } else { start_q = qof_query_create (); qof_query_set_book (start_q, gnc_get_current_book ()); /* In lieu of not "mis-using" some portion of the infrastructure by writing * a bunch of new code, we just filter out the accounts of the template * transactions. While these are in a seperate Account trees just for this * reason, the query engine makes no distinction between Account trees. * See Gnome Bug 86302. * -- jsled * * copied from gnc-ledger-display2.c:gnc_ledger_display2_gl() -- warlord * * <jsled> Alternatively, you could look for a GNC_SX_ACCOUNT [SchedAction.h] * key in the KVP frame of the split. */ { Account *tRoot; GList *al; tRoot = gnc_book_get_template_root( gnc_get_current_book() ); al = gnc_account_get_descendants( tRoot ); xaccQueryAddAccountMatch( start_q, al, QOF_GUID_MATCH_NONE, QOF_QUERY_AND ); g_list_free (al); al = NULL; tRoot = NULL; } ftd->q = start_q; /* save this to destroy it later */ } ftd->sw = gnc_search_dialog_create (type, _("Find Transaction"), params, NULL, start_q, show_q, NULL, do_find_cb, NULL, ftd, free_ftd_cb, GNC_PREFS_GROUP_SEARCH, NULL); if (!ftd->sw) { free_ftd_cb (ftd); return NULL; } return ftd->sw; }
static void gnc_reconcile_view_toggle_children (Account *account, GNCReconcileView *view, Split *split) { GList *child_accounts, *node; Transaction *transaction; /* * Need to get all splits in this transaction and identify any that are * in the same hierarchy as the account being reconciled (not necessarily * the account this split is from.) * * For each of these splits toggle them all to the same state. */ child_accounts = gnc_account_get_descendants (account); child_accounts = g_list_prepend (child_accounts, account); transaction = xaccSplitGetParent (split); for (node = xaccTransGetSplitList (transaction); node; node = node->next) { Split *other_split; Account *other_account; GNCReconcileView *current_view; GtkTreeModel *model; GtkTreeIter iter; gboolean valid; gpointer pointer; other_split = node->data; other_account = xaccSplitGetAccount (other_split); if (other_split == split) continue; /* Check this 'other' account in in the same hierarchy */ if (!g_list_find (child_accounts, other_account)) continue; /* Search our sibling view for this split first. We search the * sibling list first because that it where it is most likely to be. */ current_view = view->sibling; if (!gnc_query_view_item_in_view (GNC_QUERY_VIEW (current_view), other_split)) { /* Not in the sibling view, try this view */ current_view = view; if (!gnc_query_view_item_in_view (GNC_QUERY_VIEW (current_view), other_split)) /* We can't find it, nothing more I can do about it */ continue; } /* Found the other split. Toggle the reconciled check mark in the view... */ model = gtk_tree_view_get_model (GTK_TREE_VIEW (current_view)); valid = gtk_tree_model_get_iter_first (model, &iter); while (valid) { // Walk through the list, reading each row gtk_tree_model_get (model, &iter, REC_POINTER, &pointer, -1); if(pointer == other_split) { gboolean toggled; gtk_tree_model_get (model, &iter, REC_RECN, &toggled, -1); gtk_list_store_set (GTK_LIST_STORE (model), &iter, REC_RECN, !toggled, -1); break; } valid = gtk_tree_model_iter_next (model, &iter); } /* ...and toggle its reconciled state in the internal hash */ gnc_reconcile_view_toggle_split (current_view, other_split); } g_list_free (child_accounts); }
GtkWidget * gnc_reconcile_view_new (Account *account, GNCReconcileViewType type, time64 statement_date) { GNCReconcileView *view; GtkListStore *liststore; gboolean include_children, auto_check; GList *accounts = NULL; GList *splits; Query *query; g_return_val_if_fail (account, NULL); g_return_val_if_fail ((type == RECLIST_DEBIT) || (type == RECLIST_CREDIT), NULL); view = g_object_new (GNC_TYPE_RECONCILE_VIEW, NULL); /* Create the list store with 6 columns and add to treeview, column 0 will be a pointer to the entry */ liststore = gtk_list_store_new (6, G_TYPE_POINTER, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_BOOLEAN ); gtk_tree_view_set_model (GTK_TREE_VIEW (view), GTK_TREE_MODEL (liststore)); g_object_unref (liststore); view->account = account; view->view_type = type; view->statement_date = statement_date; query = qof_query_create_for (GNC_ID_SPLIT); qof_query_set_book (query, gnc_get_current_book ()); include_children = xaccAccountGetReconcileChildrenStatus (account); if (include_children) accounts = gnc_account_get_descendants (account); /* match the account */ accounts = g_list_prepend (accounts, account); xaccQueryAddAccountMatch (query, accounts, QOF_GUID_MATCH_ANY, QOF_QUERY_AND); g_list_free (accounts); /* limit the matches to CREDITs and DEBITs only, depending on the type */ if (type == RECLIST_CREDIT) xaccQueryAddValueMatch(query, gnc_numeric_zero (), QOF_NUMERIC_MATCH_CREDIT, QOF_COMPARE_GTE, QOF_QUERY_AND); else xaccQueryAddValueMatch(query, gnc_numeric_zero (), QOF_NUMERIC_MATCH_DEBIT, QOF_COMPARE_GTE, QOF_QUERY_AND); /* limit the matches only to Cleared and Non-reconciled splits */ xaccQueryAddClearedMatch (query, CLEARED_NO | CLEARED_CLEARED, QOF_QUERY_AND); /* Initialize the QueryList */ gnc_reconcile_view_construct (view, query); /* find the list of splits to auto-reconcile */ auto_check = gnc_prefs_get_bool (GNC_PREFS_GROUP_RECONCILE, GNC_PREF_CHECK_CLEARED); if (auto_check) { time64 statement_date_day_end = gnc_time64_get_day_end(statement_date); for (splits = qof_query_run (query); splits; splits = splits->next) { Split *split = splits->data; char recn = xaccSplitGetReconcile (split); time64 trans_date = xaccTransGetDate (xaccSplitGetParent (split)); /* Just an extra verification that our query is correct ;) */ g_assert (recn == NREC || recn == CREC); if (recn == CREC && gnc_difftime (trans_date, statement_date_day_end) <= 0) g_hash_table_insert (view->reconciled, split, split); } } /* Free the query -- we don't need it anymore */ qof_query_destroy (query); return GTK_WIDGET (view); }
Account * gnc_account_select_combo_fill (GtkWidget *combo, QofBook *book, GList *acct_types, GList *acct_commodities) { GtkListStore *store; GtkTreeIter iter; GList *list, *node; const gchar *text; g_return_val_if_fail (combo && GTK_IS_COMBO_BOX(combo), NULL); g_return_val_if_fail (book, NULL); g_return_val_if_fail (acct_types, NULL); /* Figure out if anything is set in the combo */ text = gtk_entry_get_text(GTK_ENTRY (gtk_bin_get_child(GTK_BIN (GTK_COMBO_BOX(combo))))); g_object_set_data (G_OBJECT(combo), "book", book); list = gnc_account_get_descendants (gnc_book_get_root_account (book)); /* Clear the existing list */ store = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(combo))); gtk_list_store_clear(store); /* Add the account names to the combo box */ for (node = list; node; node = node->next) { Account *account = node->data; char *name; /* Only present accounts of the appropriate type */ if (g_list_index (acct_types, (gpointer)xaccAccountGetType (account)) == -1) continue; /* Only present accounts with the right commodity, if that's a restriction */ if (acct_commodities) { if ( g_list_find_custom( acct_commodities, GINT_TO_POINTER(xaccAccountGetCommodity(account)), gnc_commodity_compare_void) == NULL ) { continue; } } name = gnc_account_get_full_name (account); gtk_list_store_append(store, &iter); gtk_list_store_set (store, &iter, 0, name, -1); /* Save the first account name in case no account name was set */ if (!text || g_strcmp0 (text, "") == 0) { text = g_strdup (name); } g_free(name); } gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0); g_list_free (list); gnc_cbwe_set_by_string(GTK_COMBO_BOX(combo), text); return gnc_account_select_combo_get_active (combo); }
static void remove_clicked (CommoditiesDialog *cd) { GNCPriceDB *pdb; GList *prices; gboolean can_delete; gnc_commodity *commodity; GtkWidget *dialog; const gchar *message, *warning; gint response; commodity = gnc_tree_view_commodity_get_selected_commodity (cd->commodity_tree); if (commodity == NULL) return; AccountList_t accounts = gnc_account_get_descendants (gnc_book_get_root_account(cd->book)); can_delete = TRUE; for (AccountList_t::const_iterator node = accounts.begin(); node != accounts.end(); node++) { Account *account = *node; if (commodity == xaccAccountGetCommodity (account)) { can_delete = FALSE; break; } } /* FIXME check for transaction references */ if (!can_delete) { const char *message = _("That commodity is currently used by " "at least one of your accounts. You may " "not delete it."); gnc_warning_dialog (cd->dialog, "%s", message); return; } pdb = gnc_pricedb_get_db (cd->book); prices = gnc_pricedb_get_prices(pdb, commodity, NULL); if (prices) { message = _("This commodity has price quotes. Are " "you sure you want to delete the selected " "commodity and its price quotes?"); warning = "delete_commodity2"; } else { message = _("Are you sure you want to delete the " "selected commodity?"); warning = "delete_commodity"; } dialog = gtk_message_dialog_new(GTK_WINDOW(cd->dialog), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_QUESTION, GTK_BUTTONS_NONE, "%s", _("Delete commodity?")); gtk_message_dialog_format_secondary_text(GTK_MESSAGE_DIALOG(dialog), "%s", message); gtk_dialog_add_buttons(GTK_DIALOG(dialog), GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, GTK_STOCK_DELETE, GTK_RESPONSE_OK, (gchar *)NULL); response = gnc_dialog_run(GTK_DIALOG(dialog), warning); gtk_widget_destroy(dialog); if (response == GTK_RESPONSE_OK) { gnc_commodity_table *ct; ct = gnc_commodity_table_get_table (cd->book); for (GList *node = prices; node; node = node->next) gnc_pricedb_remove_price(pdb, node->data); gnc_commodity_table_remove (ct, commodity); gnc_commodity_destroy (commodity); commodity = NULL; } gnc_price_list_destroy(prices); gnc_gui_refresh_all (); }