void on_finish (GtkAssistant *gtkassistant, hierarchy_data *data) { GncHierarchyAssistantFinishedCallback when_completed; gnc_commodity *com; Account * root; ENTER (" "); com = gnc_currency_edit_get_currency (GNC_CURRENCY_EDIT(data->currency_selector)); if (data->our_account_tree) { gnc_account_foreach_descendant (data->our_account_tree, (AccountCb)starting_balance_helper, data); } /* Set book options based on the user's choices */ if (data->new_book) finish_book_options_helper(data->optionwin, data->options); // delete before we suspend GUI events, and then muck with the model, // because the model doesn't seem to handle this correctly. if (data->initial_category) gtk_tree_row_reference_free(data->initial_category); delete_hierarchy_dialog (data); gnc_suspend_gui_refresh (); if (data->new_book) gtk_dialog_response(GTK_DIALOG(gnc_options_dialog_widget (data->optionwin)), GTK_RESPONSE_CANCEL); account_trees_merge(gnc_get_current_root_account(), data->our_account_tree); delete_our_account_tree (data); when_completed = data->when_completed; g_free(data); root = gnc_get_current_root_account(); xaccAccountSetCommodity(root, com); gnc_resume_gui_refresh (); if (when_completed) { (*when_completed)(); } LEAVE (" "); }
static void gnc_split_register_load_xfer_cells (SplitRegister *reg, Account *base_account) { Account *root = NULL; QuickFill *qf; ComboCell *cell; GtkListStore *store; if (base_account) root = gnc_account_get_root(base_account); if (root == NULL) root = gnc_get_current_root_account(); if (root == NULL) return; qf = gnc_get_shared_account_name_quickfill (root, QKEY, skip_cb, NULL); store = gnc_get_shared_account_name_list_store (root, QKEY, skip_cb, NULL); cell = (ComboCell *) gnc_table_layout_get_cell (reg->table->layout, XFRM_CELL); gnc_combo_cell_use_quickfill_cache (cell, qf); gnc_combo_cell_use_list_store_cache (cell, store); cell = (ComboCell *) gnc_table_layout_get_cell (reg->table->layout, MXFRM_CELL); gnc_combo_cell_use_quickfill_cache (cell, qf); gnc_combo_cell_use_list_store_cache (cell, store); }
static void scrub_all(void) { Account *root = gnc_get_current_root_account (); xaccAccountTreeScrubOrphans (root); xaccAccountTreeScrubImbalance (root); // XXX: Lots are disabled // xaccAccountTreeScrubLots (root); }
static int fill_account_list (StockSplitInfo *info, Account *selected_account) { GtkTreeRowReference *reference = NULL; GtkTreeView *view; GtkListStore *list; GtkTreeIter iter; GtkTreePath *path; GList *accounts; GList *node; gint rows = 0; gchar *full_name; view = GTK_TREE_VIEW(info->account_view); list = GTK_LIST_STORE(gtk_tree_view_get_model(view)); gtk_list_store_clear (list); accounts = gnc_account_get_descendants_sorted (gnc_get_current_root_account ()); for (node = accounts; node; node = node->next) { Account *account = node->data; GNCPrintAmountInfo print_info; const gnc_commodity *commodity; gnc_numeric balance; if (!xaccAccountIsPriced(account)) continue; balance = xaccAccountGetBalance (account); if (gnc_numeric_zero_p (balance)) continue; if (xaccAccountGetPlaceholder (account)) continue; commodity = xaccAccountGetCommodity (account); full_name = gnc_account_get_full_name (account); print_info = gnc_account_print_info (account, FALSE); gtk_list_store_append(list, &iter); gtk_list_store_set(list, &iter, SPLIT_COL_ACCOUNT, account, SPLIT_COL_FULLNAME, full_name, SPLIT_COL_MNEMONIC, gnc_commodity_get_mnemonic(commodity), SPLIT_COL_SHARES, xaccPrintAmount(balance, print_info), -1); if (account == selected_account) { path = gtk_tree_model_get_path(GTK_TREE_MODEL(list), &iter); reference = gtk_tree_row_reference_new(GTK_TREE_MODEL(list), path); gtk_tree_path_free(path); } g_free (full_name); rows++; } g_list_free(accounts); if (reference) { GtkTreeSelection* selection = gtk_tree_view_get_selection(view); path = gtk_tree_row_reference_get_path(reference); gtk_tree_row_reference_free(reference); if (path) { gtk_tree_selection_select_path(selection, path); gtk_tree_view_scroll_to_cell(view, path, NULL, TRUE, 0.5, 0.0); gtk_tree_path_free(path); } } return rows; }
/*********************************************************************** * @todo Maybe invoice checking should be done in gnc_bi_import_fix_bis (...) * rather than in here? But that is more concerned with ensuring the csv is consistent. * @param GtkListStore *store * @param guint *n_invoices_created * @param guint *n_invoices_updated * @return void ***********************************************************************/ void gnc_bi_import_create_bis (GtkListStore * store, QofBook * book, guint * n_invoices_created, guint * n_invoices_updated, gchar * type, gchar * open_mode, GString * info) { gboolean valid; GtkTreeIter iter; gchar *id, *date_opened, *owner_id, *billing_id, *notes; gchar *date, *desc, *action, *account, *quantity, *price, *disc_type, *disc_how, *discount, *taxable, *taxincluded, *tax_table; gchar *date_posted, *due_date, *account_posted, *memo_posted, *accumulatesplits; guint dummy; GncInvoice *invoice; GncEntry *entry; gint day, month, year; gnc_numeric value; GncOwner *owner; Account *acc; enum update {YES = GTK_RESPONSE_YES, NO = GTK_RESPONSE_NO} update; GtkWidget *dialog; Timespec today; InvoiceWindow *iw; gchar *new_id = NULL; gint64 denom = 0; gnc_commodity *currency; // these arguments are needed g_return_if_fail (store && book); // logic of this function only works for bills or invoices g_return_if_fail ((g_ascii_strcasecmp (type, "INVOICE") == 0) || (g_ascii_strcasecmp (type, "BILL") == 0)); // allow to call this function without statistics if (!n_invoices_created) n_invoices_created = &dummy; if (!n_invoices_updated) n_invoices_updated = &dummy; *n_invoices_created = 0; *n_invoices_updated = 0; invoice = NULL; update = NO; valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (store), &iter); while (valid) { // Walk through the list, reading each row gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, ID, &id, DATE_OPENED, &date_opened, DATE_POSTED, &date_posted, // if autoposting requested DUE_DATE, &due_date, // if autoposting requested ACCOUNT_POSTED, &account_posted, // if autoposting requested MEMO_POSTED, &memo_posted, // if autoposting requested ACCU_SPLITS, &accumulatesplits, // if autoposting requested OWNER_ID, &owner_id, BILLING_ID, &billing_id, NOTES, ¬es, DATE, &date, DESC, &desc, ACTION, &action, ACCOUNT, &account, QUANTITY, &quantity, PRICE, &price, DISC_TYPE, &disc_type, DISC_HOW, &disc_how, DISCOUNT, &discount, TAXABLE, &taxable, TAXINCLUDED, &taxincluded, TAX_TABLE, &tax_table, -1); // TODO: Assign a new invoice number if one is absent. BUT we don't want to assign a new invoice for every line!! // so we'd have to flag this up somehow or add an option in the import GUI. The former implies that we make // an assumption about what the importer (person) wants to do. It seems reasonable that a CSV file full of items with // If an invoice exists then we add to it in this current schema. // no predefined invoice number is a new invoice that's in need of a new number. // This was not designed to satisfy the need for repeat invoices however, so maybe we need a another method for this, after all // It should be easier to copy an invoice with a new ID than to go through all this malarky. if (g_ascii_strcasecmp (type, "BILL") == 0) invoice = gnc_search_bill_on_id (book, id); else if (g_ascii_strcasecmp (type, "INVOICE") == 0) invoice = gnc_search_invoice_on_id (book, id); DEBUG( "Existing %s ID: %s\n", type, gncInvoiceGetID(invoice)); // If the search is empty then there is no existing invoice so make a new one if (invoice == NULL) { DEBUG( "Creating a new : %s\n", type ); // new invoice invoice = gncInvoiceCreate (book); /* Protect against thrashing the DB and trying to write the invoice * record prematurely */ gncInvoiceBeginEdit (invoice); gncInvoiceSetID (invoice, id); owner = gncOwnerNew (); if (g_ascii_strcasecmp (type, "BILL") == 0) gncOwnerInitVendor (owner, gnc_search_vendor_on_id (book, owner_id)); else if (g_ascii_strcasecmp (type, "INVOICE") == 0) gncOwnerInitCustomer (owner, gnc_search_customer_on_id (book, owner_id)); gncInvoiceSetOwner (invoice, owner); gncInvoiceSetCurrency (invoice, gncOwnerGetCurrency (owner)); // Set the invoice currency based on the owner if (strlen (date_opened) != 0) // If a date is specified in CSV { // FIXME: Must check for the return value of qof_scan_date! qof_scan_date (date_opened, &day, &month, &year); gncInvoiceSetDateOpened (invoice, gnc_dmy2timespec (day, month, year)); } else // If no date in CSV { time64 now = gnc_time (NULL); Timespec now_timespec; timespecFromTime64 (&now_timespec, now); gncInvoiceSetDateOpened (invoice, now_timespec); } gncInvoiceSetBillingID (invoice, billing_id ? billing_id : ""); gncInvoiceSetNotes (invoice, notes ? notes : ""); gncInvoiceSetActive (invoice, TRUE); //if (g_ascii_strcasecmp(type,"INVOICE"))gncInvoiceSetBillTo( invoice, billto ); (*n_invoices_created)++; update = YES; // open new bill / invoice in a tab, if requested if (g_ascii_strcasecmp(open_mode, "ALL") == 0 || (g_ascii_strcasecmp(open_mode, "NOT_POSTED") == 0 && strlen(date_posted) == 0)) { iw = gnc_ui_invoice_edit (invoice); gnc_plugin_page_invoice_new (iw); } gncInvoiceCommitEdit (invoice); } // I want to warn the user that an existing billvoice exists, but not every // time. // An import can contain many lines usually referring to the same invoice. // NB: Posted invoices are NEVER updated. else // if invoice exists { if (gncInvoiceIsPosted (invoice)) // Is it already posted? { valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter); continue; // If already posted then never import } if (update != YES) // Pop up a dialog to ask if updates are the expected action { dialog = gtk_message_dialog_new (NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_YES_NO, "%s", _("Are you sure you have bills/invoices to update?")); update = gtk_dialog_run (GTK_DIALOG (dialog)); gtk_widget_destroy (dialog); if (update == NO) { // Cleanup and leave g_free (id); g_free (date_opened); g_free (owner_id); g_free (billing_id); g_free (notes); g_free (date); g_free (desc); g_free (action); g_free (account); g_free (quantity); g_free (price); g_free (disc_type); g_free (disc_how); g_free (discount); g_free (taxable); g_free (taxincluded); g_free (tax_table); g_free (date_posted); g_free (due_date); g_free (account_posted); g_free (memo_posted); g_free (accumulatesplits); return; } } (*n_invoices_updated)++; } // add entry to invoice/bill entry = gncEntryCreate (book); gncEntryBeginEdit(entry); currency = gncInvoiceGetCurrency(invoice); if (currency) denom = gnc_commodity_get_fraction(currency); // FIXME: Must check for the return value of qof_scan_date! qof_scan_date (date, &day, &month, &year); { GDate *date = g_date_new_dmy(day, month, year); gncEntrySetDateGDate (entry, date); g_date_free (date); } timespecFromTime64 (&today, gnc_time (NULL)); // set today to the current date gncEntrySetDateEntered (entry, today); gncEntrySetDescription (entry, desc); gncEntrySetAction (entry, action); value = gnc_numeric_zero(); gnc_exp_parser_parse (quantity, &value, NULL); gncEntrySetQuantity (entry, value); acc = gnc_account_lookup_for_register (gnc_get_current_root_account (), account); if (g_ascii_strcasecmp (type, "BILL") == 0) { gncEntrySetBillAccount (entry, acc); value = gnc_numeric_zero(); gnc_exp_parser_parse (price, &value, NULL); gncEntrySetBillPrice (entry, value); gncEntrySetBillTaxable (entry, text2bool (taxable)); gncEntrySetBillTaxIncluded (entry, text2bool (taxincluded)); gncEntrySetBillTaxTable (entry, gncTaxTableLookupByName (book, tax_table)); gncEntryCommitEdit(entry); gncBillAddEntry (invoice, entry); } else if (g_ascii_strcasecmp (type, "INVOICE") == 0) { gncEntrySetNotes (entry, notes); gncEntrySetInvAccount (entry, acc); value = gnc_numeric_zero(); gnc_exp_parser_parse (price, &value, NULL); gncEntrySetInvPrice (entry, value); gncEntrySetInvTaxable (entry, text2bool (taxable)); gncEntrySetInvTaxIncluded (entry, text2bool (taxincluded)); gncEntrySetInvTaxTable (entry, gncTaxTableLookupByName (book, tax_table)); value = gnc_numeric_zero(); gnc_exp_parser_parse (discount, &value, NULL); gncEntrySetInvDiscount (entry, value); gncEntrySetInvDiscountType (entry, text2disc_type (disc_type)); gncEntrySetInvDiscountHow (entry, text2disc_how (disc_how)); gncEntryCommitEdit(entry); gncInvoiceAddEntry (invoice, entry); } valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (store), &iter); // handle auto posting of invoices if (valid) gtk_tree_model_get (GTK_TREE_MODEL (store), &iter, ID, &new_id, -1); if (g_strcmp0 (id, new_id) != 0) { // the next invoice id is different => try to autopost this invoice if (qof_scan_date (date_posted, &day, &month, &year)) { // autopost this invoice gboolean auto_pay; Timespec d1, d2; if (g_ascii_strcasecmp (type, "INVOICE") == 0) auto_pay = gnc_prefs_get_bool (GNC_PREFS_GROUP_INVOICE, GNC_PREF_AUTO_PAY); else auto_pay = gnc_prefs_get_bool (GNC_PREFS_GROUP_BILL, GNC_PREF_AUTO_PAY); d1 = gnc_dmy2timespec (day, month, year); // FIXME: Must check for the return value of qof_scan_date! qof_scan_date (due_date, &day, &month, &year); // obtains the due date, or leaves it at date_posted d2 = gnc_dmy2timespec (day, month, year); acc = gnc_account_lookup_for_register (gnc_get_current_root_account (), account_posted); gncInvoicePostToAccount (invoice, acc, &d1, &d2, memo_posted, text2bool (accumulatesplits), auto_pay); } } } // cleanup g_free (new_id); g_free (id); g_free (date_opened); g_free (owner_id); g_free (billing_id); g_free (notes); g_free (date); g_free (desc); g_free (action); g_free (account); g_free (quantity); g_free (price); g_free (disc_type); g_free (disc_how); g_free (discount); g_free (taxable); g_free (taxincluded); g_free (tax_table); g_free (date_posted); g_free (due_date); g_free (account_posted); g_free (memo_posted); g_free (accumulatesplits); }
static void gnc_main_window_summary_refresh (GNCMainSummary * summary) { Account *root; char asset_string[256]; char profit_string[256]; GNCCurrencyAcc *currency_accum; GList *currency_list; GList *current; GNCSummarybarOptions options; root = gnc_get_current_root_account (); options.default_currency = xaccAccountGetCommodity(root); if(options.default_currency == NULL) { options.default_currency = gnc_default_currency (); } options.euro = gnc_gconf_get_bool(GCONF_GENERAL, KEY_ENABLE_EURO, NULL); options.grand_total = gnc_gconf_get_bool(GCONF_SECTION, KEY_GRAND_TOTAL, NULL); options.non_currency = gnc_gconf_get_bool(GCONF_SECTION, KEY_NON_CURRENCY, NULL); options.start_date = gnc_accounting_period_fiscal_start(); options.end_date = gnc_accounting_period_fiscal_end(); currency_list = NULL; /* grand total should be first in the list */ if (options.grand_total) { gnc_ui_get_currency_accumulator (¤cy_list, options.default_currency, TOTAL_GRAND_TOTAL); } /* Make sure there's at least one accumulator in the list. */ gnc_ui_get_currency_accumulator (¤cy_list, options.default_currency, TOTAL_SINGLE); gnc_ui_accounts_recurse(root, ¤cy_list, options); { GtkTreeIter iter; char asset_amount_string[256], profit_amount_string[256]; struct lconv *lc; lc = gnc_localeconv(); g_object_ref(summary->datamodel); gtk_combo_box_set_model(GTK_COMBO_BOX(summary->totals_combo), NULL); gtk_list_store_clear(summary->datamodel); for (current = g_list_first(currency_list); current; current = g_list_next(current)) { const char *mnemonic; gchar *total_mode_label; currency_accum = current->data; if (gnc_commodity_equiv (currency_accum->currency, gnc_locale_default_currency ())) mnemonic = lc->currency_symbol; else mnemonic = gnc_commodity_get_mnemonic (currency_accum->currency); if (mnemonic == NULL) mnemonic = ""; *asset_string = '\0'; xaccSPrintAmount(asset_amount_string, currency_accum->assets, gnc_commodity_print_info(currency_accum->currency, TRUE)); *profit_string = '\0'; xaccSPrintAmount(profit_amount_string, currency_accum->profits, gnc_commodity_print_info(currency_accum->currency, TRUE)); gtk_list_store_append(summary->datamodel, &iter); total_mode_label = get_total_mode_label(mnemonic, currency_accum->total_mode); gtk_list_store_set(summary->datamodel, &iter, COLUMN_MNEMONIC_TYPE, total_mode_label, COLUMN_ASSETS, _("Net Assets:"), COLUMN_ASSETS_VALUE, asset_amount_string, COLUMN_PROFITS, _("Profits:"), COLUMN_PROFITS_VALUE, profit_amount_string, -1); g_free(total_mode_label); } gtk_combo_box_set_model(GTK_COMBO_BOX(summary->totals_combo), GTK_TREE_MODEL(summary->datamodel)); g_object_unref(summary->datamodel); gtk_combo_box_set_active(GTK_COMBO_BOX(summary->totals_combo), 0); } /* Free the list we created for this */ for (current = g_list_first(currency_list); current; current = g_list_next(current)) { g_free(current->data); } g_list_free(currency_list); }
static gboolean gnc_html_register_url_cb (const char *location, const char *label, gboolean new_window, GNCURLResult *result) { GncPluginPage *page = NULL; GNCSplitReg * gsr = NULL; Split * split = NULL; Account * account = NULL; Transaction * trans; GList * node; QofBook * book = gnc_get_current_book(); GncGUID guid; QofInstance * entity = NULL; g_return_val_if_fail (location != NULL, FALSE); g_return_val_if_fail (result != NULL, FALSE); result->load_to_stream = FALSE; /* href="gnc-register:account=My Bank Account" */ if (strncmp("account=", location, 8) == 0) { account = gnc_account_lookup_by_full_name (gnc_get_current_root_account (), location + 8); } /* href="gnc-register:guid=12345678901234567890123456789012" */ else if (strncmp ("acct-guid=", location, strlen ("acct-guid=")) == 0) { if (!validate_type("acct-guid=", location, GNC_ID_ACCOUNT, result, &guid, &entity)) return FALSE; account = GNC_ACCOUNT(entity); } else if (strncmp ("trans-guid=", location, strlen ("trans-guid=")) == 0) { if (!validate_type("trans-guid=", location, GNC_ID_TRANS, result, &guid, &entity)) return FALSE; trans = (Transaction *) entity; for (node = xaccTransGetSplitList (trans); node; node = node->next) { split = node->data; account = xaccSplitGetAccount(split); if (account) break; } if (!account) { result->error_message = g_strdup_printf (_("Transaction with no Accounts: %s"), location); return FALSE; } } else if (strncmp ("split-guid=", location, strlen ("split-guid=")) == 0) { if (!validate_type("split-guid=", location, GNC_ID_SPLIT, result, &guid, &entity)) return FALSE; split = (Split *) entity; account = xaccSplitGetAccount(split); } else { result->error_message = g_strdup_printf (_("Unsupported entity type: %s"), location); return FALSE; } page = gnc_plugin_page_register_new (account, FALSE); gnc_main_window_open_page (NULL, page); if (split) { gsr = gnc_plugin_page_register_get_gsr(page); gnc_split_reg_jump_to_split( gsr, split ); } return TRUE; }
/************************************************** * load * * load the settings from a state key file **************************************************/ bool CsvTransSettings::load (void) { if (trans_preset_is_reserved_name (m_name)) return true; GError *key_error = nullptr; m_load_error = false; auto group = csv_group_prefix + m_name; auto keyfile = gnc_state_get_current (); m_skip_start_lines = g_key_file_get_integer (keyfile, group.c_str(), CSV_SKIP_START, &key_error); m_load_error |= handle_load_error (&key_error, group); m_skip_end_lines = g_key_file_get_integer (keyfile, group.c_str(), CSV_SKIP_END, &key_error); m_load_error |= handle_load_error (&key_error, group); m_skip_alt_lines = g_key_file_get_boolean (keyfile, group.c_str(), CSV_SKIP_ALT, &key_error); m_load_error |= handle_load_error (&key_error, group); m_multi_split = g_key_file_get_boolean (keyfile, group.c_str(), CSV_MULTI_SPLIT, &key_error); m_load_error |= handle_load_error (&key_error, group); auto csv_format = g_key_file_get_boolean (keyfile, group.c_str(), CSV_FORMAT, &key_error); if (key_error) csv_format = true; // default to true, but above command will return false in case of error m_load_error |= handle_load_error (&key_error, group); if (csv_format) m_file_format = GncImpFileFormat::CSV; else m_file_format = GncImpFileFormat::FIXED_WIDTH; gchar *key_char = g_key_file_get_string (keyfile, group.c_str(), CSV_SEP, &key_error); if (key_char && *key_char != '\0') m_separators = key_char; m_load_error |= handle_load_error (&key_error, group); if (key_char) g_free (key_char); m_date_format = g_key_file_get_integer (keyfile, group.c_str(), CSV_DATE, &key_error); m_load_error |= handle_load_error (&key_error, group); m_currency_format = g_key_file_get_integer (keyfile, group.c_str(), CSV_CURRENCY, &key_error); m_load_error |= handle_load_error (&key_error, group); key_char = g_key_file_get_string (keyfile, group.c_str(), CSV_ENCODING, &key_error); if (key_char && *key_char != '\0') m_encoding = key_char; else m_encoding = "UTF-8"; m_load_error |= handle_load_error (&key_error, group); if (key_char) g_free (key_char); key_char = g_key_file_get_string (keyfile, group.c_str(), CSV_ACCOUNT, &key_error); if (key_char && *key_char != '\0') m_base_account = gnc_account_lookup_by_full_name (gnc_get_current_root_account(), key_char); m_load_error |= handle_load_error (&key_error, group); if (key_char) g_free (key_char); m_column_types.clear(); gsize list_len; gchar** col_types_str = g_key_file_get_string_list (keyfile, group.c_str(), CSV_COL_TYPES, &list_len, &key_error); for (uint32_t i = 0; i < list_len; i++) { auto col_types_it = std::find_if (gnc_csv_col_type_strs.begin(), gnc_csv_col_type_strs.end(), test_prop_type_str (col_types_str[i])); if (col_types_it != gnc_csv_col_type_strs.end()) { /* Found a valid column type. Now check whether it is allowed * in the selected mode (two-split vs multi-split) */ auto prop = sanitize_trans_prop (col_types_it->first, m_multi_split); m_column_types.push_back(prop); if (prop != col_types_it->first) PWARN("Found column type '%s', but this is blacklisted when multi-split mode is %s. " "Inserting column type 'NONE' instead'.", col_types_it->second, m_multi_split ? "enabled" : "disabled"); } else PWARN("Found invalid column type '%s'. Inserting column type 'NONE' instead'.", col_types_str[i]); } if (col_types_str) g_strfreev (col_types_str); m_column_widths.clear(); gint *col_widths_int = g_key_file_get_integer_list (keyfile, group.c_str(), CSV_COL_WIDTHS, &list_len, &key_error); for (uint32_t i = 0; i < list_len; i++) { if (col_widths_int[i] > 0) m_column_widths.push_back(col_widths_int[i]); } m_load_error |= handle_load_error (&key_error, group); if (col_widths_int) g_free (col_widths_int); return m_load_error; }