mirror of
https://github.com/Gnucash/gnucash.git
synced 2025-02-25 18:55:30 -06:00
Merge branch 'maint'
This commit is contained in:
commit
017ab06939
@ -1116,6 +1116,7 @@ gnc_scm2query_and_terms (SCM and_terms, query_version_t vers)
|
||||
if (q_and)
|
||||
{
|
||||
q_new = qof_query_merge (q, q_and, QOF_QUERY_AND);
|
||||
qof_query_destroy (q_and);
|
||||
|
||||
if (q_new)
|
||||
{
|
||||
@ -1158,6 +1159,7 @@ gnc_scm2query_or_terms (SCM or_terms, query_version_t vers)
|
||||
if (q_or)
|
||||
{
|
||||
q_new = qof_query_merge (q, q_or, QOF_QUERY_OR);
|
||||
qof_query_destroy (q_or);
|
||||
|
||||
if (q_new)
|
||||
{
|
||||
|
@ -2,6 +2,7 @@ from unittest import main
|
||||
|
||||
from gnucash import Transaction, Book, Account, Split
|
||||
from unittest_support import *
|
||||
from datetime import datetime, timezone
|
||||
|
||||
from test_book import BookSession
|
||||
|
||||
@ -138,5 +139,12 @@ class TestTransaction(TransactionSession):
|
||||
self.trans.SetNotes(NOTE)
|
||||
self.assertEqual( NOTE, self.trans.GetNotes() )
|
||||
|
||||
def test_date(self):
|
||||
ZERODATE=datetime(1970, 1, 1, 0, 0, 0, tzinfo=timezone.utc)
|
||||
DATE=datetime(2020, 2, 20, 10, 59, 0, tzinfo=timezone.utc)
|
||||
self.assertEqual(ZERODATE, self.trans.GetDate().astimezone(timezone.utc))
|
||||
self.trans.SetDate(DATE.day, DATE.month, DATE.year)
|
||||
self.assertEqual(DATE, self.trans.GetDate().astimezone(timezone.utc))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
@ -372,6 +372,7 @@ sort_by_xxx_value (xaccGetBalanceInCurrencyFn fn,
|
||||
gpointer user_data)
|
||||
{
|
||||
const Account *account_a, *account_b;
|
||||
const gnc_commodity *cur = gnc_default_currency();
|
||||
gnc_numeric balance_a, balance_b;
|
||||
gint result;
|
||||
|
||||
@ -379,8 +380,8 @@ sort_by_xxx_value (xaccGetBalanceInCurrencyFn fn,
|
||||
sort_cb_setup (f_model, f_iter_a, f_iter_b, &account_a, &account_b);
|
||||
|
||||
/* Get balances */
|
||||
balance_a = gnc_ui_account_get_balance_full(fn, account_a, recurse, NULL, NULL);
|
||||
balance_b = gnc_ui_account_get_balance_full(fn, account_b, recurse, NULL, NULL);
|
||||
balance_a = gnc_ui_account_get_balance_full(fn, account_a, recurse, NULL, cur);
|
||||
balance_b = gnc_ui_account_get_balance_full(fn, account_b, recurse, NULL, cur);
|
||||
|
||||
result = gnc_numeric_compare(balance_a, balance_b);
|
||||
if (result != 0)
|
||||
|
@ -930,6 +930,8 @@ gnc_customer_search (GtkWindow *parent, GncCustomer *start, QofBook *book)
|
||||
/* Build the column list in reverse order */
|
||||
if (columns == NULL)
|
||||
{
|
||||
columns = gnc_search_param_prepend (columns, _("Shipping Contact"), NULL, type,
|
||||
CUSTOMER_SHIPADDR, ADDRESS_NAME, NULL);
|
||||
columns = gnc_search_param_prepend (columns, _("Contact"), NULL, type,
|
||||
CUSTOMER_ADDR, ADDRESS_NAME, NULL);
|
||||
columns = gnc_search_param_prepend (columns, _("Company"), NULL, type,
|
||||
|
@ -136,10 +136,10 @@ gnc_report_system_file_stream_cb (const char *location, char ** data, int *len)
|
||||
static gboolean
|
||||
gnc_report_system_report_stream_cb (const char *location, char ** data, int *len)
|
||||
{
|
||||
gboolean ok;
|
||||
gchar *captured_str;
|
||||
|
||||
ok = gnc_run_report_id_string_with_error_handling (location, data, &captured_str);
|
||||
gchar *captured_str = NULL;
|
||||
gboolean ok =
|
||||
gnc_run_report_id_string_with_error_handling (location, data,
|
||||
&captured_str);
|
||||
|
||||
if (!ok)
|
||||
{
|
||||
|
@ -2120,6 +2120,9 @@ recn_destroy_cb (GtkWidget *w, gpointer data)
|
||||
if (recnData->delete_refresh)
|
||||
gnc_resume_gui_refresh ();
|
||||
|
||||
//Disable the actions, the handlers try to access recnData
|
||||
gtk_action_group_set_sensitive(recnData->action_group, FALSE);
|
||||
|
||||
g_free (recnData);
|
||||
}
|
||||
|
||||
|
@ -30,6 +30,7 @@
|
||||
#endif
|
||||
|
||||
#include "gnucash-commands.hpp"
|
||||
#include "gnucash-core-app.hpp"
|
||||
|
||||
extern "C" {
|
||||
#include <gnc-engine-guile.h>
|
||||
@ -173,8 +174,7 @@ scm_run_report (void *data,
|
||||
scm_c_use_module ("gnucash reports");
|
||||
|
||||
gnc_report_init ();
|
||||
// load_system_config();
|
||||
// load_user_config();
|
||||
Gnucash::gnc_load_scm_config();
|
||||
gnc_prefs_init ();
|
||||
qof_event_suspend ();
|
||||
|
||||
@ -303,6 +303,7 @@ scm_report_show (void *data,
|
||||
scm_c_use_module ("gnucash app-utils");
|
||||
scm_c_use_module ("gnucash reports");
|
||||
gnc_report_init ();
|
||||
Gnucash::gnc_load_scm_config();
|
||||
|
||||
if (!args->file_to_load.empty())
|
||||
{
|
||||
@ -334,6 +335,7 @@ scm_report_list ([[maybe_unused]] void *data,
|
||||
scm_c_use_module ("gnucash app-utils");
|
||||
scm_c_use_module ("gnucash reports");
|
||||
gnc_report_init ();
|
||||
Gnucash::gnc_load_scm_config();
|
||||
|
||||
scm_call_1 (scm_c_eval_string ("gnc:cmdline-report-list"),
|
||||
scm_current_output_port ());
|
||||
|
@ -40,5 +40,9 @@ namespace Gnucash {
|
||||
int report_list (void);
|
||||
int report_show (const bo_str& file_to_load,
|
||||
const bo_str& run_report);
|
||||
|
||||
// A helper function to load scm config files (SYSCONFIGDIR/config
|
||||
// and USERCONFIGDIR/config-user.scm) on demand
|
||||
void gnc_load_scm_config(void);
|
||||
}
|
||||
#endif
|
||||
|
@ -86,25 +86,6 @@ gnc_print_unstable_message(void)
|
||||
<< bl::format (bl::translate ("To find the last stable version, please refer to {1}")) % PACKAGE_URL << "\n";
|
||||
}
|
||||
|
||||
static gboolean
|
||||
try_load_config_array(const gchar *fns[])
|
||||
{
|
||||
gchar *filename;
|
||||
int i;
|
||||
|
||||
for (i = 0; fns[i]; i++)
|
||||
{
|
||||
filename = gnc_build_userdata_path(fns[i]);
|
||||
if (gfec_try_load(filename))
|
||||
{
|
||||
g_free(filename);
|
||||
return TRUE;
|
||||
}
|
||||
g_free(filename);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
update_message(const gchar *msg)
|
||||
{
|
||||
@ -112,52 +93,30 @@ update_message(const gchar *msg)
|
||||
g_message("%s", msg);
|
||||
}
|
||||
|
||||
static void
|
||||
load_system_config(void)
|
||||
void
|
||||
Gnucash::gnc_load_scm_config (void)
|
||||
{
|
||||
static int is_system_config_loaded = FALSE;
|
||||
gchar *system_config_dir;
|
||||
gchar *system_config;
|
||||
|
||||
if (is_system_config_loaded) return;
|
||||
|
||||
update_message("loading system configuration");
|
||||
system_config_dir = gnc_path_get_pkgsysconfdir();
|
||||
system_config = g_build_filename(system_config_dir, "config", nullptr);
|
||||
is_system_config_loaded = gfec_try_load(system_config);
|
||||
g_free(system_config_dir);
|
||||
g_free(system_config);
|
||||
}
|
||||
|
||||
static void
|
||||
load_user_config(void)
|
||||
{
|
||||
/* Don't continue adding to this list. When 3.0 rolls around bump
|
||||
the 2.4 files off the list. */
|
||||
static const gchar *saved_report_files[] =
|
||||
static auto is_system_config_loaded = false;
|
||||
if (!is_system_config_loaded)
|
||||
{
|
||||
SAVED_REPORTS_FILE, SAVED_REPORTS_FILE_OLD_REV, NULL
|
||||
};
|
||||
static const gchar *stylesheet_files[] = { "stylesheets-2.0", NULL};
|
||||
static int is_user_config_loaded = FALSE;
|
||||
|
||||
if (is_user_config_loaded)
|
||||
return;
|
||||
else is_user_config_loaded = TRUE;
|
||||
|
||||
update_message("loading user configuration");
|
||||
{
|
||||
gchar *config_filename;
|
||||
config_filename = g_build_filename (gnc_userconfig_dir (),
|
||||
"config-user.scm", (char *)NULL);
|
||||
gfec_try_load(config_filename);
|
||||
g_free(config_filename);
|
||||
auto msg = bl::translate ("Loading system scm configuration...").str (gnc_get_boost_locale());
|
||||
update_message (msg.c_str());
|
||||
auto system_config_dir = gnc_path_get_pkgsysconfdir ();
|
||||
auto system_config = g_build_filename (system_config_dir, "config", nullptr);
|
||||
is_system_config_loaded = gfec_try_load (system_config);
|
||||
g_free (system_config_dir);
|
||||
g_free (system_config);
|
||||
}
|
||||
|
||||
update_message("loading saved reports");
|
||||
try_load_config_array(saved_report_files);
|
||||
update_message("loading stylesheets");
|
||||
try_load_config_array(stylesheet_files);
|
||||
static auto is_user_config_loaded = false;
|
||||
if (!is_user_config_loaded)
|
||||
{
|
||||
auto msg = bl::translate ("Loading user scm configuration...").str (gnc_get_boost_locale());
|
||||
update_message (msg.c_str());
|
||||
auto config_filename = g_build_filename (gnc_userconfig_dir (), "config-user.scm", nullptr);
|
||||
is_user_config_loaded = gfec_try_load (config_filename);
|
||||
g_free (config_filename);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -70,5 +70,6 @@ private:
|
||||
char *sys_locale = nullptr;
|
||||
};
|
||||
|
||||
void gnc_load_scm_config(void);
|
||||
}
|
||||
#endif
|
||||
|
@ -73,56 +73,6 @@ namespace bl = boost::locale;
|
||||
static QofLogModule log_module = GNC_MOD_GUI;
|
||||
static gchar *userdata_migration_msg = NULL;
|
||||
|
||||
static void
|
||||
update_message(const gchar *msg)
|
||||
{
|
||||
gnc_update_splash_screen(msg, GNC_SPLASH_PERCENTAGE_UNKNOWN);
|
||||
g_message("%s", msg);
|
||||
}
|
||||
|
||||
static void
|
||||
load_system_config(void)
|
||||
{
|
||||
static int is_system_config_loaded = FALSE;
|
||||
gchar *system_config_dir;
|
||||
gchar *system_config;
|
||||
|
||||
if (is_system_config_loaded) return;
|
||||
|
||||
update_message("loading system configuration");
|
||||
system_config_dir = gnc_path_get_pkgsysconfdir();
|
||||
system_config = g_build_filename(system_config_dir, "config", nullptr);
|
||||
is_system_config_loaded = gfec_try_load(system_config);
|
||||
g_free(system_config_dir);
|
||||
g_free(system_config);
|
||||
}
|
||||
|
||||
static void
|
||||
load_user_config(void)
|
||||
{
|
||||
/* Don't continue adding to this list. When 3.0 rolls around bump
|
||||
the 2.4 files off the list. */
|
||||
static const gchar *saved_report_files[] =
|
||||
{
|
||||
SAVED_REPORTS_FILE, SAVED_REPORTS_FILE_OLD_REV, NULL
|
||||
};
|
||||
static const gchar *stylesheet_files[] = { "stylesheets-2.0", NULL};
|
||||
static int is_user_config_loaded = FALSE;
|
||||
|
||||
if (is_user_config_loaded)
|
||||
return;
|
||||
else is_user_config_loaded = TRUE;
|
||||
|
||||
update_message("loading user configuration");
|
||||
{
|
||||
gchar *config_filename;
|
||||
config_filename = g_build_filename (gnc_userconfig_dir (),
|
||||
"config-user.scm", (char *)NULL);
|
||||
gfec_try_load(config_filename);
|
||||
g_free(config_filename);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
load_gnucash_plugins()
|
||||
{
|
||||
@ -207,11 +157,10 @@ scm_run_gnucash (void *data, [[maybe_unused]] int argc, [[maybe_unused]] char **
|
||||
load_gnucash_plugins();
|
||||
load_gnucash_modules();
|
||||
|
||||
/* Load the config before starting up the gui. This insures that
|
||||
/* Load the scm config files before starting up the gui. This ensures that
|
||||
* custom reports have been read into memory before the Reports
|
||||
* menu is created. */
|
||||
load_system_config();
|
||||
load_user_config();
|
||||
Gnucash::gnc_load_scm_config();
|
||||
|
||||
/* Setting-up the report menu must come after the module
|
||||
loading but before the gui initializat*ion. */
|
||||
|
@ -721,11 +721,11 @@
|
||||
</child>
|
||||
<child>
|
||||
<object class="GtkCheckButton" id="pref/dialogs.sxs.since-last-run/review-transactions">
|
||||
<property name="label" translatable="yes">Set 'Re_view Created Transactions' as default</property>
|
||||
<property name="label" translatable="yes">Re_view created transactions</property>
|
||||
<property name="visible">True</property>
|
||||
<property name="can_focus">True</property>
|
||||
<property name="receives_default">False</property>
|
||||
<property name="tooltip_text" translatable="yes">Set 'Review Created Transactions' as the default in the 'Since Last Run' dialog.</property>
|
||||
<property name="tooltip_text" translatable="yes">Set 'Review created transactions' as the default in the "since last run" dialog.</property>
|
||||
<property name="halign">start</property>
|
||||
<property name="use_underline">True</property>
|
||||
<property name="draw_indicator">True</property>
|
||||
|
@ -1048,6 +1048,93 @@ gnc_import_process_trans_item (GncImportMatchMap *matchmap,
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/********************************************************************\
|
||||
* check_trans_online_id() Callback function used by
|
||||
* gnc_import_exists_online_id. Takes pointers to transaction and split,
|
||||
* returns 0 if their online_ids do NOT match, or if the split
|
||||
* belongs to the transaction
|
||||
\********************************************************************/
|
||||
static gint check_trans_online_id(Transaction *trans1, void *user_data)
|
||||
{
|
||||
Account *account;
|
||||
Split *split1;
|
||||
Split *split2 = user_data;
|
||||
const gchar *online_id1;
|
||||
const gchar *online_id2;
|
||||
|
||||
account = xaccSplitGetAccount(split2);
|
||||
split1 = xaccTransFindSplitByAccount(trans1, account);
|
||||
if (split1 == split2)
|
||||
return 0;
|
||||
|
||||
/* hack - we really want to iterate over the _splits_ of the account
|
||||
instead of the transactions */
|
||||
g_assert(split1 != NULL);
|
||||
|
||||
if (gnc_import_split_has_online_id(split1))
|
||||
online_id1 = gnc_import_get_split_online_id(split1);
|
||||
else
|
||||
online_id1 = gnc_import_get_trans_online_id(trans1);
|
||||
|
||||
online_id2 = gnc_import_get_split_online_id(split2);
|
||||
|
||||
if ((online_id1 == NULL) ||
|
||||
(online_id2 == NULL) ||
|
||||
(strcmp(online_id1, online_id2) != 0))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
/*printf("test_trans_online_id(): Duplicate found\n");*/
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
/** Checks whether the given transaction's online_id already exists in
|
||||
its parent account. */
|
||||
gboolean gnc_import_exists_online_id (Transaction *trans, GHashTable* acct_id_hash)
|
||||
{
|
||||
gboolean online_id_exists = FALSE;
|
||||
Account *dest_acct;
|
||||
Split *source_split;
|
||||
|
||||
/* Look for an online_id in the first split */
|
||||
source_split = xaccTransGetSplit(trans, 0);
|
||||
g_assert(source_split);
|
||||
|
||||
// No online id, no point in continuing. We'd crash if we tried.
|
||||
if (!gnc_import_get_split_online_id (source_split))
|
||||
return FALSE;
|
||||
// Create a hash per account of a hash of all split IDs. Then the test below will be fast if
|
||||
// we have many transactions to import.
|
||||
dest_acct = xaccSplitGetAccount (source_split);
|
||||
if (!g_hash_table_contains (acct_id_hash, dest_acct))
|
||||
{
|
||||
GHashTable* new_hash = g_hash_table_new (g_str_hash, g_str_equal);
|
||||
GList* split_list = xaccAccountGetSplitList(dest_acct);
|
||||
g_hash_table_insert (acct_id_hash, dest_acct, new_hash);
|
||||
for (;split_list;split_list=split_list->next)
|
||||
{
|
||||
if (gnc_import_split_has_online_id (split_list->data))
|
||||
g_hash_table_add (new_hash, (void*) gnc_import_get_split_online_id (split_list->data));
|
||||
}
|
||||
}
|
||||
online_id_exists = g_hash_table_contains (g_hash_table_lookup (acct_id_hash, dest_acct),
|
||||
gnc_import_get_split_online_id (source_split));
|
||||
|
||||
/* If it does, abort the process for this transaction, since it is
|
||||
already in the system. */
|
||||
if (online_id_exists == TRUE)
|
||||
{
|
||||
DEBUG("%s", "Transaction with same online ID exists, destroying current transaction");
|
||||
xaccTransDestroy(trans);
|
||||
xaccTransCommitEdit(trans);
|
||||
}
|
||||
return online_id_exists;
|
||||
}
|
||||
|
||||
|
||||
/* ******************************************************************
|
||||
*/
|
||||
|
||||
|
@ -57,6 +57,15 @@ typedef enum _action
|
||||
/** @name Non-GUI Functions */
|
||||
/*@{*/
|
||||
|
||||
/** Checks whether the given transaction's online_id already exists in
|
||||
* its parent account. The given transaction has to be open for
|
||||
* editing. If a matching online_id exists, the transaction is
|
||||
* destroyed (!) and TRUE is returned, otherwise FALSE is returned.
|
||||
*
|
||||
* @param trans The transaction for which to check for an existing
|
||||
* online_id. */
|
||||
gboolean gnc_import_exists_online_id (Transaction *trans, GHashTable* acct_id_hash);
|
||||
|
||||
/** Evaluates the match between trans_info and split using the provided parameters.
|
||||
*
|
||||
* @param trans_info The TransInfo for the imported transaction
|
||||
|
@ -76,6 +76,7 @@ struct _main_matcher_info
|
||||
gboolean add_toggled; // flag to indicate that add has been toggled to stop selection
|
||||
gint id;
|
||||
GSList* temp_trans_list; // Temporary list of imported transactions
|
||||
GHashTable* acct_id_hash; // Hash table, per account, of list of transaction IDs.
|
||||
GSList* edited_accounts; // List of accounts currently edited.
|
||||
};
|
||||
|
||||
@ -143,6 +144,14 @@ static gboolean query_tooltip_tree_view_cb (GtkWidget *widget, gint x, gint y,
|
||||
gpointer user_data);
|
||||
/* end local prototypes */
|
||||
|
||||
static
|
||||
gboolean delete_hash (gpointer key, gpointer value, gpointer user_data)
|
||||
{
|
||||
// Value is a hash table that needs to be destroyed.
|
||||
g_hash_table_destroy (value);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
update_all_balances (GNCImportMainMatcher *info)
|
||||
{
|
||||
@ -209,6 +218,8 @@ gnc_gen_trans_list_delete (GNCImportMainMatcher *info)
|
||||
// We've deferred balance computations on many accounts. Let's do it now that we're done.
|
||||
update_all_balances (info);
|
||||
|
||||
g_hash_table_foreach_remove (info->acct_id_hash, delete_hash, NULL);
|
||||
info->acct_id_hash = NULL;
|
||||
g_free (info);
|
||||
}
|
||||
|
||||
@ -1133,6 +1144,8 @@ gnc_gen_trans_init_view (GNCImportMainMatcher *info,
|
||||
G_CALLBACK(gnc_gen_trans_onButtonPressed_cb), info);
|
||||
g_signal_connect (view, "popup-menu",
|
||||
G_CALLBACK(gnc_gen_trans_onPopupMenu_cb), info);
|
||||
|
||||
info->acct_id_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
|
||||
}
|
||||
|
||||
static void
|
||||
@ -1713,11 +1726,16 @@ gnc_gen_trans_list_add_trans_with_ref_id (GNCImportMainMatcher *gui, Transaction
|
||||
g_assert (gui);
|
||||
g_assert (trans);
|
||||
|
||||
if (gnc_import_exists_online_id (trans, gui->acct_id_hash))
|
||||
return;
|
||||
else
|
||||
{
|
||||
transaction_info = gnc_import_TransInfo_new (trans, NULL);
|
||||
gnc_import_TransInfo_set_ref_id (transaction_info, ref_id);
|
||||
// It's much faster to gather the imported transactions into a GSList than directly into the
|
||||
// treeview.
|
||||
gui->temp_trans_list = g_slist_prepend (gui->temp_trans_list, transaction_info);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -1781,6 +1799,8 @@ create_hash_of_potential_matches (GList *candidate_txns,
|
||||
{
|
||||
Account* split_account;
|
||||
GSList* split_list;
|
||||
if (gnc_import_split_has_online_id (candidate->data))
|
||||
continue;
|
||||
split_account = xaccSplitGetAccount (candidate->data);
|
||||
/* g_hash_table_steal_extended would do the two calls in one shot but is
|
||||
* not available until GLib 2.58.
|
||||
|
@ -57,6 +57,29 @@ void gnc_import_set_acc_online_id (Account *account, const gchar *id)
|
||||
xaccAccountCommitEdit (account);
|
||||
}
|
||||
|
||||
const gchar * gnc_import_get_trans_online_id (Transaction * transaction)
|
||||
{
|
||||
gchar *id = NULL;
|
||||
qof_instance_get (QOF_INSTANCE (transaction), "online-id", &id, NULL);
|
||||
return id;
|
||||
}
|
||||
/* Not actually used */
|
||||
void gnc_import_set_trans_online_id (Transaction *transaction,
|
||||
const gchar *id)
|
||||
{
|
||||
g_return_if_fail (transaction != NULL);
|
||||
xaccTransBeginEdit (transaction);
|
||||
qof_instance_set (QOF_INSTANCE (transaction), "online-id", id, NULL);
|
||||
xaccTransCommitEdit (transaction);
|
||||
}
|
||||
|
||||
gboolean gnc_import_trans_has_online_id(Transaction * transaction)
|
||||
{
|
||||
const gchar * online_id;
|
||||
online_id = gnc_import_get_trans_online_id(transaction);
|
||||
return (online_id != NULL && strlen(online_id) > 0);
|
||||
}
|
||||
|
||||
const gchar * gnc_import_get_split_online_id (Split * split)
|
||||
{
|
||||
gchar *id = NULL;
|
||||
|
@ -49,6 +49,17 @@ const gchar * gnc_import_get_acc_online_id(Account * account);
|
||||
void gnc_import_set_acc_online_id(Account * account,
|
||||
const gchar * string_value);
|
||||
/** @} */
|
||||
/** @name Setter-getters
|
||||
Setter and getter functions for the online_id field for
|
||||
Transactions.
|
||||
@{
|
||||
*/
|
||||
const gchar * gnc_import_get_trans_online_id(Transaction * transaction);
|
||||
void gnc_import_set_trans_online_id(Transaction * transaction,
|
||||
const gchar * string_value);
|
||||
/** @} */
|
||||
|
||||
gboolean gnc_import_trans_has_online_id(Transaction * transaction);
|
||||
|
||||
/** @name Setter-getters
|
||||
Setter and getter functions for the online_id field for
|
||||
|
@ -94,15 +94,6 @@
|
||||
(lambda () (cons 'absolute (current-time)))
|
||||
#f 'absolute #f ))
|
||||
|
||||
;; This is another date option, but the user can also select
|
||||
;; the time.
|
||||
(add-option
|
||||
(gnc:make-date-option
|
||||
(N_ "Hello, World!") (N_ "Time and Date Option")
|
||||
"e" (N_ "This is a date option with time.")
|
||||
(lambda () (cons 'absolute (current-time)))
|
||||
#t 'absolute #f ))
|
||||
|
||||
(add-option
|
||||
(gnc:make-date-option
|
||||
(N_ "Hello, World!") (N_ "Combo Date Option")
|
||||
@ -234,8 +225,6 @@ option like this.")
|
||||
(string-val (op-value "Hello, World!" "String Option"))
|
||||
(date-val (gnc:date-option-absolute-time
|
||||
(op-value "Hello, World!" "Just a Date Option")))
|
||||
(date2-val (gnc:date-option-absolute-time
|
||||
(op-value "Hello, World!" "Time and Date Option")))
|
||||
(rel-date-val (gnc:date-option-absolute-time
|
||||
(op-value "Hello, World!" "Relative Date Option")))
|
||||
(combo-date-val (gnc:date-option-absolute-time
|
||||
@ -258,7 +247,6 @@ option like this.")
|
||||
;; qof-print-date
|
||||
(let ((time-string (gnc-print-time64 (current-time) "%X"))
|
||||
(date-string (gnc-print-time64 date-val "%x"))
|
||||
(date-string2 (gnc-print-time64 date2-val "%x %X"))
|
||||
(rel-date-string (gnc-print-time64 rel-date-val "%x"))
|
||||
(combo-date-string (gnc-print-time64 combo-date-val "%x")))
|
||||
|
||||
@ -369,11 +357,6 @@ new, totally cool report, consult the mailing list ~a.")
|
||||
(G_ "The date option is ~a.")
|
||||
(gnc:html-markup-b date-string)))
|
||||
|
||||
(gnc:html-markup-p
|
||||
(gnc:html-markup/format
|
||||
(G_ "The date and time option is ~a.")
|
||||
(gnc:html-markup-b date-string2)))
|
||||
|
||||
(gnc:html-markup-p
|
||||
(gnc:html-markup/format
|
||||
(G_ "The relative date option is ~a.")
|
||||
|
@ -719,6 +719,10 @@ the option '~a'."))
|
||||
(begin
|
||||
(rpterror-earlier "date" item (car full-list))
|
||||
0)))
|
||||
(if show-time
|
||||
(issue-deprecation-warning
|
||||
(format #f "Date options with time of day values are deprecated and will be removed in GnuCash 5.")))
|
||||
|
||||
(let* ((value (default-getter))
|
||||
(value->string (lambda ()
|
||||
(string-append "'" (gnc:value->string value)))))
|
||||
|
@ -171,8 +171,11 @@ GncXmlBackend::session_end()
|
||||
if (!m_linkfile.empty())
|
||||
g_unlink (m_linkfile.c_str());
|
||||
|
||||
if (m_lockfd > 0)
|
||||
if (m_lockfd != -1)
|
||||
{
|
||||
close (m_lockfd);
|
||||
m_lockfd = -1;
|
||||
}
|
||||
|
||||
if (!m_lockfile.empty())
|
||||
{
|
||||
@ -638,12 +641,13 @@ GncXmlBackend::get_file_lock ()
|
||||
{
|
||||
/* oops .. file is locked by another user .. */
|
||||
set_error(ERR_BACKEND_LOCKED);
|
||||
m_lockfile.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
m_lockfd = g_open (m_lockfile.c_str(), O_RDWR | O_CREAT | O_EXCL ,
|
||||
S_IRUSR | S_IWUSR);
|
||||
if (m_lockfd < 0)
|
||||
if (m_lockfd == -1)
|
||||
{
|
||||
/* oops .. we can't create the lockfile .. */
|
||||
switch (errno)
|
||||
@ -661,87 +665,11 @@ GncXmlBackend::get_file_lock ()
|
||||
PWARN ("Unable to create the lockfile %s: %s",
|
||||
m_lockfile.c_str(), strerror(errno));
|
||||
set_error(be_err);
|
||||
m_lockfile.clear();
|
||||
return false;
|
||||
}
|
||||
|
||||
/* OK, now work around some NFS atomic lock race condition
|
||||
* mumbo-jumbo. We do this by linking a unique file, and
|
||||
* then examining the link count. At least that's what the
|
||||
* NFS programmers guide suggests.
|
||||
* Note: the "unique filename" must be unique for the
|
||||
* triplet filename-host-process, otherwise accidental
|
||||
* aliases can occur.
|
||||
*/
|
||||
|
||||
/* apparently, even this code may not work for some NFS
|
||||
* implementations. In the long run, I am told that
|
||||
* ftp.debian.org
|
||||
* /pub/debian/dists/unstable/main/source/libs/liblockfile_0.1-6.tar.gz
|
||||
* provides a better long-term solution.
|
||||
*/
|
||||
|
||||
#ifndef G_OS_WIN32
|
||||
auto path = m_lockfile.find_last_of('.');
|
||||
std::stringstream linkfile;
|
||||
if (path != std::string::npos)
|
||||
linkfile << m_lockfile.substr(0, path);
|
||||
else
|
||||
linkfile << m_lockfile;
|
||||
linkfile << "." << gethostid() << "." << getpid() << ".LNK";
|
||||
rc = link (m_lockfile.c_str(), linkfile.str().c_str());
|
||||
if (rc)
|
||||
{
|
||||
/* If hard links aren't supported, just allow the lock. */
|
||||
if (errno == EPERM || errno == ENOSYS
|
||||
# ifdef EOPNOTSUPP
|
||||
|| errno == EOPNOTSUPP
|
||||
# endif
|
||||
# ifdef ENOTSUP
|
||||
|| errno == ENOTSUP
|
||||
# endif
|
||||
)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Otherwise, something else is wrong. */
|
||||
set_error(ERR_BACKEND_LOCKED);
|
||||
g_unlink (linkfile.str().c_str());
|
||||
close (m_lockfd);
|
||||
g_unlink (m_lockfile.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
rc = g_stat (m_lockfile.c_str(), &statbuf);
|
||||
if (rc)
|
||||
{
|
||||
/* oops .. stat failed! This can't happen! */
|
||||
set_error(ERR_BACKEND_LOCKED);
|
||||
std::string msg{"Failed to stat lockfile "};
|
||||
set_message(msg + m_lockfile);
|
||||
g_unlink (linkfile.str().c_str());
|
||||
close (m_lockfd);
|
||||
g_unlink (m_lockfile.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
if (statbuf.st_nlink != 2)
|
||||
{
|
||||
set_error(ERR_BACKEND_LOCKED);
|
||||
g_unlink (linkfile.str().c_str());
|
||||
close (m_lockfd);
|
||||
g_unlink (m_lockfile.c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
m_linkfile = linkfile.str();
|
||||
return true;
|
||||
|
||||
#else /* ifndef G_OS_WIN32 */
|
||||
/* On windows, there is no NFS and the open(,O_CREAT | O_EXCL)
|
||||
is sufficient for locking. */
|
||||
return true;
|
||||
#endif /* ifndef G_OS_WIN32 */
|
||||
}
|
||||
|
||||
bool
|
||||
|
@ -60,7 +60,7 @@ private:
|
||||
std::string m_dirname;
|
||||
std::string m_lockfile;
|
||||
std::string m_linkfile;
|
||||
int m_lockfd;
|
||||
int m_lockfd = -1;
|
||||
|
||||
QofBook* m_book = nullptr; /* The primary, main open book */
|
||||
};
|
||||
|
@ -127,7 +127,7 @@ sxtg_book_begin (QofBook *book)
|
||||
static void
|
||||
sxtg_book_end (QofBook *book)
|
||||
{
|
||||
// gnc_book_set_template_root (book, NULL);
|
||||
gnc_book_set_template_root (book, NULL);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
@ -612,7 +612,7 @@ gnc_transaction_get_commodity_imbalance (Transaction *trans,
|
||||
|
||||
/* GFunc wrapper for xaccSplitDestroy */
|
||||
static void
|
||||
destroy_split (void* ptr, void* data)
|
||||
destroy_split (void* ptr)
|
||||
{
|
||||
Split *split = GNC_SPLIT (ptr);
|
||||
if (split)
|
||||
@ -642,7 +642,10 @@ xaccTransClearTradingSplits (Transaction *trans)
|
||||
return;
|
||||
|
||||
xaccTransBeginEdit (trans);
|
||||
g_list_foreach (trading_splits, destroy_split, NULL);
|
||||
/* destroy_splits doesn't actually free the splits but this gets
|
||||
* the list ifself freed.
|
||||
*/
|
||||
g_list_free_full (trading_splits, destroy_split);
|
||||
xaccTransCommitEdit (trans);
|
||||
}
|
||||
|
||||
|
@ -2107,6 +2107,7 @@ xaccSplitGetOtherSplit (const Split *split)
|
||||
{
|
||||
Split *s = n->data;
|
||||
if ((s == split) ||
|
||||
(!xaccTransStillHasSplit(trans, s)) ||
|
||||
(xaccAccountGetType (xaccSplitGetAccount (s)) == ACCT_TYPE_TRADING) ||
|
||||
(qof_instance_has_slot (QOF_INSTANCE (s), "lot-split")))
|
||||
continue;
|
||||
|
@ -73,8 +73,8 @@ cashobjects_register(void)
|
||||
g_return_val_if_fail(xaccAccountRegister(), FALSE);
|
||||
g_return_val_if_fail ( xaccTransRegister(), FALSE);
|
||||
g_return_val_if_fail ( xaccSplitRegister(), FALSE);
|
||||
g_return_val_if_fail ( SXRegister (), FALSE);
|
||||
g_return_val_if_fail ( gnc_sxtt_register(), FALSE);
|
||||
g_return_val_if_fail ( SXRegister (), FALSE);
|
||||
g_return_val_if_fail(gnc_pricedb_register(), FALSE);
|
||||
g_return_val_if_fail (gnc_budget_register(), FALSE);
|
||||
g_return_val_if_fail ( gnc_lot_register (), FALSE);
|
||||
|
@ -704,7 +704,7 @@ GncTaxTableList * gncTaxTableGetTables (QofBook *book)
|
||||
if (!book) return NULL;
|
||||
|
||||
bi = qof_book_get_data (book, _GNC_MOD_NAME);
|
||||
return bi->tables;
|
||||
return bi ? bi->tables : NULL;
|
||||
}
|
||||
|
||||
const char *gncTaxTableGetName (const GncTaxTable *table)
|
||||
|
@ -60,6 +60,15 @@ xaccAccountForEachTransaction(const Account *acc, TransactionCallback proc,
|
||||
return mockaccount ? mockaccount->for_each_transaction(proc, data) : 0;
|
||||
}
|
||||
|
||||
SplitList *
|
||||
xaccAccountGetSplitList (const Account *account)
|
||||
{
|
||||
SCOPED_TRACE("");
|
||||
auto mockaccount = gnc_mockaccount(account);
|
||||
return mockaccount ? mockaccount->xaccAccountGetSplitList() : nullptr;
|
||||
}
|
||||
|
||||
|
||||
GncImportMatchMap *
|
||||
gnc_account_imap_create_imap (Account *acc)
|
||||
{
|
||||
|
@ -43,6 +43,7 @@ public:
|
||||
MOCK_METHOD0(commit_edit, void());
|
||||
MOCK_CONST_METHOD0(get_book, QofBook*());
|
||||
MOCK_CONST_METHOD2(for_each_transaction, gint(TransactionCallback, void*));
|
||||
MOCK_CONST_METHOD0(xaccAccountGetSplitList, SplitList*());
|
||||
MOCK_METHOD0(create_imap, GncImportMatchMap*());
|
||||
|
||||
protected:
|
||||
|
@ -36,6 +36,7 @@ if ($( != 0) {
|
||||
exit 0 if ($input ne "y");
|
||||
}
|
||||
|
||||
CPAN::Shell->install('Test2'); #Required by an F::Q dependency but cpan doesn't notice.
|
||||
CPAN::Shell->install('Date::Manip'); #Required by gnc-fq-helper
|
||||
CPAN::Shell->install('Finance::Quote');
|
||||
|
||||
|
12
po/de.po
12
po/de.po
@ -36,7 +36,7 @@ msgstr ""
|
||||
"Report-Msgid-Bugs-To: https://bugs.gnucash.org/enter_bug."
|
||||
"cgi?product=GnuCash&component=Translations\n"
|
||||
"POT-Creation-Date: 2021-06-30 07:34+0200\n"
|
||||
"PO-Revision-Date: 2021-08-16 20:35+0000\n"
|
||||
"PO-Revision-Date: 2021-09-05 21:35+0000\n"
|
||||
"Last-Translator: Christian Wehling <christian.wehling@web.de>\n"
|
||||
"Language-Team: German <https://hosted.weblate.org/projects/gnucash/gnucash/"
|
||||
"de/>\n"
|
||||
@ -45,7 +45,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=n != 1;\n"
|
||||
"X-Generator: Weblate 4.8-dev\n"
|
||||
"X-Generator: Weblate 4.8.1-dev\n"
|
||||
|
||||
#: bindings/guile/commodity-table.scm:44
|
||||
msgid "ALL NON-CURRENCY"
|
||||
@ -17134,7 +17134,7 @@ msgstr "Zahl, Datum, Zeit"
|
||||
# erreichbar. Können wir das vereinheitlichen?
|
||||
#: gnucash/gtkbuilder/dialog-preferences.glade:1417
|
||||
msgid "Perform account list _setup on new file"
|
||||
msgstr "Bei neuer Datei erstellen: Konten_einrichtung anzeigen"
|
||||
msgstr "Bei neuer Datei erstellen: Konten_einrichtung starten"
|
||||
|
||||
#: gnucash/gtkbuilder/dialog-preferences.glade:1423
|
||||
msgid "Present the new account list dialog when you choose File->New File."
|
||||
@ -18328,7 +18328,7 @@ msgstr "<b>Voreinstellungen Buchungseditor</b>"
|
||||
|
||||
#: gnucash/gtkbuilder/dialog-sx.glade:545
|
||||
msgid "_Run when data file opened"
|
||||
msgstr "Seit-Letztem-Aufruf Fenster starten, wenn eine _Datei geöffnet wird"
|
||||
msgstr "Ausführen, wenn eine _Datei geöffnet wird"
|
||||
|
||||
#: gnucash/gtkbuilder/dialog-sx.glade:549
|
||||
msgid "Run the \"since last run\" process when a file is opened."
|
||||
@ -18388,10 +18388,8 @@ msgid "R_emind in advance"
|
||||
msgstr "Im Voraus er_innern"
|
||||
|
||||
#: gnucash/gtkbuilder/dialog-sx.glade:724
|
||||
#, fuzzy
|
||||
#| msgid "_Review created transactions"
|
||||
msgid "Set 'Re_view Created Transactions' as default"
|
||||
msgstr "Erzeugte Buchungen _durchsehen"
|
||||
msgstr "'Erstellte _Buchungen durchsehen' als Standard festlegen"
|
||||
|
||||
#: gnucash/gtkbuilder/dialog-sx.glade:728
|
||||
msgid ""
|
||||
|
42
po/zh_CN.po
42
po/zh_CN.po
@ -23,7 +23,7 @@ msgstr ""
|
||||
"Report-Msgid-Bugs-To: https://bugs.gnucash.org/enter_bug."
|
||||
"cgi?product=GnuCash&component=Translations\n"
|
||||
"POT-Creation-Date: 2021-06-30 07:34+0200\n"
|
||||
"PO-Revision-Date: 2021-08-31 14:33+0000\n"
|
||||
"PO-Revision-Date: 2021-09-10 16:33+0000\n"
|
||||
"Last-Translator: TianXing_Yi <ytx.cash@gmail.com>\n"
|
||||
"Language-Team: Chinese (Simplified) <https://hosted.weblate.org/projects/"
|
||||
"gnucash/gnucash/zh_Hans/>\n"
|
||||
@ -32,7 +32,7 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Generator: Weblate 4.8.1-dev\n"
|
||||
"X-Generator: Weblate 4.9-dev\n"
|
||||
"X-Bugs: Report translation errors to the Language-Team address.\n"
|
||||
|
||||
#: bindings/guile/commodity-table.scm:44
|
||||
@ -2162,7 +2162,7 @@ msgstr "入账日期"
|
||||
|
||||
#: gnucash/gnome/dialog-invoice.c:872
|
||||
msgid "Post to Account"
|
||||
msgstr "入账到科目"
|
||||
msgstr "入账科目"
|
||||
|
||||
#: gnucash/gnome/dialog-invoice.c:873
|
||||
msgid "Accumulate Splits?"
|
||||
@ -3643,7 +3643,7 @@ msgstr "打开查找项目对话框"
|
||||
#: gnucash/gnome/gnc-plugin-business.c:238
|
||||
#: gnucash/gnome/gnc-plugin-business.c:271
|
||||
msgid "_Process Payment..."
|
||||
msgstr "处理收付(_P)..."
|
||||
msgstr "收付(_P)..."
|
||||
|
||||
#: gnucash/gnome/gnc-plugin-business.c:196
|
||||
#: gnucash/gnome/gnc-plugin-business.c:239
|
||||
@ -4946,7 +4946,7 @@ msgstr "显示员工报表"
|
||||
|
||||
#: gnucash/gnome/gnc-plugin-page-owner-tree.c:293
|
||||
msgid "New Voucher"
|
||||
msgstr "新建支出凭证"
|
||||
msgstr "新建报销"
|
||||
|
||||
#: gnucash/gnome/gnc-plugin-page-owner-tree.c:446
|
||||
msgid "Owners"
|
||||
@ -9239,7 +9239,7 @@ msgstr "重新计算(_R)"
|
||||
#: gnucash/report/trep-engine.scm:168 gnucash/report/trep-engine.scm:956
|
||||
#: gnucash/report/trep-engine.scm:1045
|
||||
msgid "Account Name"
|
||||
msgstr "科目名称"
|
||||
msgstr "名称"
|
||||
|
||||
#: gnucash/gnome-utils/gnc-tree-view-account.c:816
|
||||
#: gnucash/gnome-utils/gnc-tree-view-split-reg.c:2919
|
||||
@ -10877,13 +10877,13 @@ msgstr ""
|
||||
msgid ""
|
||||
"Set \"Review Created Transactions\" as the default for the \"since last run"
|
||||
"\" dialog."
|
||||
msgstr ""
|
||||
msgstr "将 \"审查创建的交易 \"设为 \"自上次运行以来 \"对话框的默认值。"
|
||||
|
||||
#: gnucash/gschemas/org.gnucash.dialogs.sxs.gschema.xml.in:28
|
||||
msgid ""
|
||||
"This setting controls whether as default the \"review created transactions\" "
|
||||
"is set for the \"since last run\" dialog."
|
||||
msgstr ""
|
||||
msgstr "此设置控制 \"自上次运行以来 \"对话框是否默认设置 \"审查已创建的交易\"。"
|
||||
|
||||
#: gnucash/gschemas/org.gnucash.dialogs.sxs.gschema.xml.in:35
|
||||
msgid "Set the \"auto create\" flag by default"
|
||||
@ -11238,7 +11238,7 @@ msgstr "新打开的标签页前置,而非最后"
|
||||
msgid ""
|
||||
"If active, new tabs are opened adjacent to current tab. If inactive, the new "
|
||||
"tabs are opened instead at the end."
|
||||
msgstr ""
|
||||
msgstr "如果激活,新标签会在当前标签的旁边打开。如果不激活,新标签将在最后打开。"
|
||||
|
||||
#: gnucash/gschemas/org.gnucash.gschema.xml.in:140
|
||||
#: gnucash/gtkbuilder/dialog-preferences.glade:940
|
||||
@ -11330,7 +11330,7 @@ msgstr "最大的几个月又回到过去。"
|
||||
msgid ""
|
||||
"Dates will be completed so that they are close to the current date. Enter "
|
||||
"the maximum number of months to go backwards in time when completing dates."
|
||||
msgstr "录入月份和本月差值在限额内(小于等于),即本年;超出(大于)为明年。"
|
||||
msgstr "相隔月数小于等于设定值为本年,大于设定值为明年。"
|
||||
|
||||
#: gnucash/gschemas/org.gnucash.gschema.xml.in:180
|
||||
msgid "Show Horizontal Grid Lines"
|
||||
@ -15973,7 +15973,7 @@ msgstr "<b>日期补全</b>"
|
||||
|
||||
#: gnucash/gtkbuilder/dialog-preferences.glade:1112
|
||||
msgid "When a date is entered without year, it should be taken"
|
||||
msgstr "输入的日期没有年份时,其应属于"
|
||||
msgstr "没有年份的日期,其应属于"
|
||||
|
||||
#: gnucash/gtkbuilder/dialog-preferences.glade:1128
|
||||
msgid ""
|
||||
@ -15984,9 +15984,7 @@ msgstr "日期年份补全为本年。"
|
||||
msgid ""
|
||||
"In a sliding 12-month window starting this\n"
|
||||
"many months before the current month"
|
||||
msgstr ""
|
||||
"从现在开始这个次数,它追溯到过去,\n"
|
||||
"它被认为是那个月的12个月内的日期"
|
||||
msgstr "相隔月数定年份"
|
||||
|
||||
#: gnucash/gtkbuilder/dialog-preferences.glade:1165
|
||||
msgid "Enter number of months."
|
||||
@ -16257,13 +16255,13 @@ msgstr "不可能的匹配日阈值 (_U)"
|
||||
msgid ""
|
||||
"A transaction whose date is within the threshold is likely to be a match. "
|
||||
"Default is 4 days."
|
||||
msgstr ""
|
||||
msgstr "日期在阈值内的交易可能是匹配的。默认为4天。"
|
||||
|
||||
#: gnucash/gtkbuilder/dialog-preferences.glade:2340
|
||||
msgid ""
|
||||
"A transaction whose date is outside the threshold is unlikely to be a match. "
|
||||
"Default is 14 days."
|
||||
msgstr ""
|
||||
msgstr "日期在阈值之外的交易不太可能是匹配的。默认为14天。"
|
||||
|
||||
#: gnucash/gtkbuilder/dialog-preferences.glade:2385
|
||||
msgid "<b>Checks</b>"
|
||||
@ -17203,7 +17201,7 @@ msgstr "默认复核已创建交易(_R)"
|
||||
msgid ""
|
||||
"Set 'Review Created Transactions' as the default in the 'Since Last Run' "
|
||||
"dialog."
|
||||
msgstr ""
|
||||
msgstr "在 \"自上次运行 \"对话框中,将 \"审查创建的交易 \"设置为默认值。"
|
||||
|
||||
#: gnucash/gtkbuilder/dialog-sx.glade:765
|
||||
msgid "Edit Scheduled Transaction"
|
||||
@ -17356,7 +17354,7 @@ msgstr "GnuCash 每日提示"
|
||||
|
||||
#: gnucash/gtkbuilder/dialog-totd.glade:26
|
||||
msgid "_Previous"
|
||||
msgstr "去年末(_P)"
|
||||
msgstr "上一个(_P)"
|
||||
|
||||
#: gnucash/gtkbuilder/dialog-totd.glade:41
|
||||
msgid "_Next"
|
||||
@ -21349,7 +21347,7 @@ msgstr "小计"
|
||||
#: gnucash/report/reports/standard/owner-report.scm:56
|
||||
#: libgnucash/app-utils/business-options.scm:78
|
||||
msgid "Tax"
|
||||
msgstr "税务"
|
||||
msgstr "税额"
|
||||
|
||||
#: gnucash/register/ledger-core/gncEntryLedgerModel.c:127
|
||||
msgid "Billable?"
|
||||
@ -21968,7 +21966,7 @@ msgstr "价格信息的来源。"
|
||||
|
||||
#: gnucash/report/options-utilities.scm:144
|
||||
msgid "Average cost of purchases weighted by volume"
|
||||
msgstr ""
|
||||
msgstr "按数量加权的平均采购成本"
|
||||
|
||||
#: gnucash/report/options-utilities.scm:145
|
||||
msgid "Weighted average of all transactions in the past"
|
||||
@ -22103,7 +22101,7 @@ msgstr "收入支出(_I)"
|
||||
|
||||
#: gnucash/report/report-core.scm:154
|
||||
msgid "_Taxes"
|
||||
msgstr "税务(_U)"
|
||||
msgstr "税额(_U)"
|
||||
|
||||
#: gnucash/report/report-core.scm:155
|
||||
msgid "E_xamples"
|
||||
@ -24537,7 +24535,7 @@ msgstr "以逐条求和计算么?"
|
||||
|
||||
#: gnucash/report/reports/standard/budget-barchart.scm:142
|
||||
msgid "Select which chart type to use."
|
||||
msgstr ""
|
||||
msgstr "选择要使用的图表类型。"
|
||||
|
||||
#: gnucash/report/reports/standard/budget-barchart.scm:144
|
||||
#: gnucash/report/reports/standard/category-barchart.scm:156
|
||||
|
Loading…
Reference in New Issue
Block a user