Merge branch 'maint'

This commit is contained in:
John Ralls 2016-01-11 15:29:18 -08:00
commit 8428c81e2f
50 changed files with 13786 additions and 21106 deletions

3
.gitignore vendored
View File

@ -1,5 +1,8 @@
*.bak
*.gmo
*.gschema.xml
*.gschema.xml.in
*.gschema.valid
*.la
*.lo
*.o

5932
ChangeLog

File diff suppressed because it is too large Load Diff

1294
ChangeLog.1999 Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

1372
ChangeLog.2015 Normal file

File diff suppressed because it is too large Load Diff

View File

@ -27,6 +27,10 @@ dist_doc_DATA = \
ChangeLog.2005 \
ChangeLog.2004 \
ChangeLog.2003 \
ChangeLog.2002 \
ChangeLog.2001 \
ChangeLog.2000 \
ChangeLog.1999 \
DOCUMENTERS \
HACKING \
INSTALL \
@ -215,7 +219,7 @@ ChangeLog: NEWS
--stringparam include-rev "yes" $(abs_srcdir)/macros/svn2cl.xsl - > $(abs_builddir)/$@ ; \
else \
if test x$(VCS_TYPE) = xgit ; then \
"$(GIT_CMD)" log --format="%ad %aN %n%n%x09* %s%d%n" --date=short --since=2013-01-01 > $(abs_builddir)/$@ ; \
"$(GIT_CMD)" log --format="%ad %aN %n%n%x09* %s%d%n" --date=short --since=2016-01-01 > $(abs_builddir)/$@ ; \
else \
touch $(abs_builddir)/$@ ; \
echo "Note: not in svn or git. ChangeLog not regenerated." ; \

31
NEWS
View File

@ -1,5 +1,36 @@
Version history:
------- -------
2.6.11 - 11 January 2016
Announcement: GnuCash 2.6.11 Release 2016-01-11
GnuCash 2.6.11 released
The GnuCash development team announces GnuCash 2.6.11, a snap release
to correct a QIF import regression and the eleventh maintenance
release in the 2.6-stable series.
The following bugs are fixed:
Bug 680104 - Scheduled Tranaction formula not calculated when variables
are mixed with constants.
Bug 756335 - When importing, date selection causes exit crash.
Bug 759570 - Postponing a repeating SX skips over the instance.
Bug 759674 - GNUCash crashes when importing invoices or bills with
delimited import.
Bug 759859 - Reconcilation does not convert transactions' currency to
the main one making reconcilation impossible.
Bug 760052 - missing flag translatable in Custom Report.
Bug 760079 - Translations comments: Remove translatable flag from
placeholder labels in dialog date-close.
Bug 760398 - Cancelling the creation of a duplicate bill or invoice
doesn't reset the invoice number counter
Other repairs that weren't marked as bugs in git:
Add Account.AssignLots to python bindings.
Allow panel that provides information about TXF categories to be adjusted by the user in the Income Tax Information dialog under Edit->Tax Report Options.
Minor improvement to information provided about TXF categories in the Income Tax Information dialog under Edit->Tax Report Options.
Updated Translations: German
2.6.10 - 20 December 2015
Announcement: GnuCash 2.6.10 Release 2015-12-20
GnuCash 2.6.10 released

784
po/az.po

File diff suppressed because it is too large Load Diff

785
po/ca.po

File diff suppressed because it is too large Load Diff

783
po/cs.po

File diff suppressed because it is too large Load Diff

1065
po/da.po

File diff suppressed because it is too large Load Diff

516
po/de.po

File diff suppressed because it is too large Load Diff

789
po/eu.po

File diff suppressed because it is too large Load Diff

780
po/fa.po

File diff suppressed because it is too large Load Diff

783
po/ja.po

File diff suppressed because it is too large Load Diff

786
po/nl.po

File diff suppressed because it is too large Load Diff

790
po/pt.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

7894
po/ro.po

File diff suppressed because it is too large Load Diff

783
po/rw.po

File diff suppressed because it is too large Load Diff

781
po/sk.po

File diff suppressed because it is too large Load Diff

841
po/sr.po

File diff suppressed because it is too large Load Diff

783
po/sv.po

File diff suppressed because it is too large Load Diff

783
po/tr.po

File diff suppressed because it is too large Load Diff

783
po/uk.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -259,8 +259,7 @@ gnc_sx_get_template_transaction_account(const SchedXaction *sx)
void
gnc_sx_get_variables(SchedXaction *sx, GHashTable *var_hash)
{
Account *sx_template_acct;
sx_template_acct = gnc_sx_get_template_transaction_account(sx);
Account *sx_template_acct = gnc_sx_get_template_transaction_account(sx);
xaccAccountForEachTransaction(sx_template_acct, _get_vars_helper, var_hash);
}
@ -353,7 +352,7 @@ _gnc_sx_gen_instances(gpointer *data, gpointer user_data)
const GDate *range_end = (const GDate*)user_data;
GDate creation_end, remind_end;
GDate cur_date;
void *sequence_ctx;
SXTmpStateData *temporal_state = gnc_sx_create_temporal_state(sx);
instances->sx = sx;
@ -374,37 +373,45 @@ _gnc_sx_gen_instances(gpointer *data, gpointer user_data)
g_date_clear(&inst_date, 1);
inst_date = xaccSchedXactionGetNextInstance(sx, postponed->data);
seq_num = gnc_sx_get_instance_count(sx, postponed->data);
inst = gnc_sx_instance_new(instances, SX_INSTANCE_STATE_POSTPONED, &inst_date, postponed->data, seq_num);
instances->instance_list = g_list_append(instances->instance_list, inst);
inst = gnc_sx_instance_new(instances, SX_INSTANCE_STATE_POSTPONED,
&inst_date, postponed->data, seq_num);
instances->instance_list =
g_list_append(instances->instance_list, inst);
gnc_sx_destroy_temporal_state(temporal_state);
temporal_state = gnc_sx_clone_temporal_state(postponed->data);
gnc_sx_incr_temporal_state(sx, temporal_state);
}
}
/* to-create */
g_date_clear(&cur_date, 1);
sequence_ctx = gnc_sx_create_temporal_state(sx);
cur_date = xaccSchedXactionGetInstanceAfter(sx, &cur_date, sequence_ctx);
cur_date = xaccSchedXactionGetNextInstance(sx, temporal_state);
instances->next_instance_date = cur_date;
while (g_date_valid(&cur_date) && g_date_compare(&cur_date, &creation_end) <= 0)
{
GncSxInstance *inst;
int seq_num;
seq_num = gnc_sx_get_instance_count(sx, sequence_ctx);
inst = gnc_sx_instance_new(instances, SX_INSTANCE_STATE_TO_CREATE, &cur_date, sequence_ctx, seq_num);
seq_num = gnc_sx_get_instance_count(sx, temporal_state);
inst = gnc_sx_instance_new(instances, SX_INSTANCE_STATE_TO_CREATE,
&cur_date, temporal_state, seq_num);
instances->instance_list = g_list_append(instances->instance_list, inst);
gnc_sx_incr_temporal_state(sx, sequence_ctx);
cur_date = xaccSchedXactionGetInstanceAfter(sx, &cur_date, sequence_ctx);
gnc_sx_incr_temporal_state(sx, temporal_state);
cur_date = xaccSchedXactionGetNextInstance(sx, temporal_state);
}
/* reminders */
while (g_date_valid(&cur_date) && g_date_compare(&cur_date, &remind_end) <= 0)
while (g_date_valid(&cur_date) &&
g_date_compare(&cur_date, &remind_end) <= 0)
{
GncSxInstance *inst;
int seq_num;
seq_num = gnc_sx_get_instance_count(sx, sequence_ctx);
inst = gnc_sx_instance_new(instances, SX_INSTANCE_STATE_REMINDER, &cur_date, sequence_ctx, seq_num);
instances->instance_list = g_list_append(instances->instance_list, inst);
gnc_sx_incr_temporal_state(sx, sequence_ctx);
cur_date = xaccSchedXactionGetInstanceAfter(sx, &cur_date, sequence_ctx);
seq_num = gnc_sx_get_instance_count(sx, temporal_state);
inst = gnc_sx_instance_new(instances, SX_INSTANCE_STATE_REMINDER,
&cur_date, temporal_state, seq_num);
instances->instance_list = g_list_append(instances->instance_list,
inst);
gnc_sx_incr_temporal_state(sx, temporal_state);
cur_date = xaccSchedXactionGetNextInstance(sx, temporal_state);
}
return instances;
@ -468,17 +475,17 @@ gnc_sx_instance_model_get_type(void)
if (type == 0)
{
static const GTypeInfo info =
{
sizeof (GncSxInstanceModelClass),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc)gnc_sx_instance_model_class_init, /* class_init */
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GncSxInstanceModel),
0, /* n_preallocs */
(GInstanceInitFunc)gnc_sx_instance_model_init /* instance_init */
};
{
sizeof (GncSxInstanceModelClass),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc)gnc_sx_instance_model_class_init, /* class_init */
NULL, /* class_finalize */
NULL, /* class_data */
sizeof (GncSxInstanceModel),
0, /* n_preallocs */
(GInstanceInitFunc)gnc_sx_instance_model_init /* instance_init */
};
type = g_type_register_static (G_TYPE_OBJECT,
"GncSxInstanceModelType",
&info, 0);
@ -667,8 +674,8 @@ _gnc_sx_instance_event_handler(QofInstance *ent, QofEventId event_type, gpointer
{
/* it's moved from disabled to enabled, add the instances */
instances->sx_instance_list
= g_list_append(instances->sx_instance_list,
_gnc_sx_gen_instances((gpointer)sx, (gpointer) & instances->range_end));
= g_list_append(instances->sx_instance_list,
_gnc_sx_gen_instances((gpointer)sx, (gpointer) & instances->range_end));
g_signal_emit_by_name(instances, "added", (gpointer)sx);
}
}
@ -698,8 +705,8 @@ _gnc_sx_instance_event_handler(QofInstance *ent, QofEventId event_type, gpointer
{
/* generate instances, add to instance list, emit update. */
instances->sx_instance_list
= g_list_append(instances->sx_instance_list,
_gnc_sx_gen_instances((gpointer)sx, (gpointer) & instances->range_end));
= g_list_append(instances->sx_instance_list,
_gnc_sx_gen_instances((gpointer)sx, (gpointer) & instances->range_end));
g_signal_emit_by_name(instances, "added", (gpointer)sx);
}
}
@ -838,10 +845,10 @@ gnc_sx_instance_model_update_sx_instances(GncSxInstanceModel *model, SchedXactio
{
gchar *to_add_key = (gchar*)var_iter->data;
if (!g_hash_table_lookup_extended(
inst->variable_bindings, to_add_key, NULL, NULL))
inst->variable_bindings, to_add_key, NULL, NULL))
{
GncSxVariable *parent_var
= g_hash_table_lookup(existing->variable_names, to_add_key);
= g_hash_table_lookup(existing->variable_names, to_add_key);
GncSxVariable *var_copy;
g_assert(parent_var != NULL);
@ -874,8 +881,8 @@ static void
increment_sx_state(GncSxInstance *inst, GDate **last_occur_date, int *instance_count, int *remain_occur_count)
{
if (!g_date_valid(*last_occur_date)
|| (g_date_valid(*last_occur_date)
&& g_date_compare(*last_occur_date, &inst->date) <= 0))
|| (g_date_valid(*last_occur_date)
&& g_date_compare(*last_occur_date, &inst->date) <= 0))
{
*last_occur_date = &inst->date;
}
@ -942,13 +949,15 @@ _get_sx_formula_value(const SchedXaction* sx,
numeric_key, &numeric_val,
NULL);
if (numeric_val != NULL &&
if ((variable_bindings == NULL ||
g_hash_table_size (variable_bindings) == 0) &&
numeric_val != NULL &&
gnc_numeric_check(*numeric_val) == GNC_ERROR_OK &&
!gnc_numeric_zero_p(*numeric_val))
{
/* Already a valid non-zero result? Then return and don't
* parse the string. Luckily we avoid any locale problems with
* decimal points here! Phew. */
/* If there are no variables to parse and we had a valid numeric stored
* then we can skip parsing the formual, which might save some
* localization problems with separators. */
numeric->num = numeric_val->num;
numeric->denom = numeric_val->denom;
return;
@ -988,19 +997,98 @@ _get_sx_formula_value(const SchedXaction* sx,
}
static void
_get_credit_formula_value(GncSxInstance *instance, const Split *template_split, gnc_numeric *credit_num, GList **creation_errors)
_get_credit_formula_value(GncSxInstance *instance,
const Split *template_split, gnc_numeric *credit_num,
GList **creation_errors)
{
_get_sx_formula_value(instance->parent->sx, template_split, credit_num,
creation_errors, "sx-credit-formula",
"sx-credit-numeric", instance->variable_bindings);
creation_errors, "sx-credit-formula",
"sx-credit-numeric", instance->variable_bindings);
}
static void
_get_debit_formula_value(GncSxInstance *instance, const Split *template_split, gnc_numeric *debit_num, GList **creation_errors)
_get_debit_formula_value(GncSxInstance *instance, const Split *template_split,
gnc_numeric *debit_num, GList **creation_errors)
{
_get_sx_formula_value(instance->parent->sx, template_split, debit_num,
creation_errors, "sx-debit-formula",
"sx-debit-numeric", instance->variable_bindings);
creation_errors, "sx-debit-formula",
"sx-debit-numeric", instance->variable_bindings);
}
static gnc_numeric
split_apply_formulas (const Split *split, SxTxnCreationData* creation_data)
{
gnc_numeric credit_num = gnc_numeric_zero();
gnc_numeric debit_num = gnc_numeric_zero();
gnc_numeric final;
gint gncn_error;
SchedXaction *sx = creation_data->instance->parent->sx;
_get_credit_formula_value(creation_data->instance, split, &credit_num,
creation_data->creation_errors);
_get_debit_formula_value(creation_data->instance, split, &debit_num,
creation_data->creation_errors);
final = gnc_numeric_sub_fixed(debit_num, credit_num);
gncn_error = gnc_numeric_check(final);
if (gncn_error != GNC_ERROR_OK)
{
GString *err = g_string_new("");
g_string_printf(err, "error %d in SX [%s] final gnc_numeric value, using 0 instead",
gncn_error, xaccSchedXactionGetName(sx));
g_critical("%s", err->str);
if (creation_data->creation_errors != NULL)
*creation_data->creation_errors =
g_list_append(*creation_data->creation_errors, err);
else
g_string_free(err, TRUE);
final = gnc_numeric_zero();
}
return final;
}
static void
split_apply_exchange_rate (Split *split, GHashTable *bindings,
gnc_commodity *first_cmdty,
gnc_commodity *split_cmdty, gnc_numeric *final)
{
GString *exchange_rate_var_name = g_string_sized_new(16);
GncSxVariable *exchange_rate_var;
gnc_numeric amt;
gnc_numeric exchange_rate = gnc_numeric_create (1, 1);
g_string_printf(exchange_rate_var_name, "%s -> %s",
gnc_commodity_get_mnemonic(first_cmdty),
gnc_commodity_get_mnemonic(split_cmdty));
g_debug("var_name is %s -> %s", gnc_commodity_get_mnemonic(first_cmdty),
gnc_commodity_get_mnemonic(split_cmdty));
exchange_rate_var =
(GncSxVariable*)g_hash_table_lookup(bindings,
exchange_rate_var_name->str);
if (exchange_rate_var != NULL)
{
exchange_rate = exchange_rate_var->value;
g_debug("exchange_rate is %s", gnc_numeric_to_string (exchange_rate));
}
g_string_free(exchange_rate_var_name, TRUE);
if (!gnc_commodity_is_currency (split_cmdty))
amt = gnc_numeric_div(*final, exchange_rate,
gnc_commodity_get_fraction (split_cmdty),
GNC_HOW_RND_ROUND_HALF_UP);
else
amt = gnc_numeric_mul(*final, exchange_rate, 1000,
GNC_HOW_RND_ROUND_HALF_UP);
g_debug("amount is %s for memo split '%s'", gnc_numeric_to_string (amt),
xaccSplitGetMemo (split));
xaccSplitSetAmount(split, amt); /* marks split dirty */
}
static gboolean
@ -1011,9 +1099,8 @@ create_each_transaction_helper(Transaction *template_txn, void *user_data)
Split *copying_split;
gnc_commodity *first_cmdty = NULL;
gboolean err_flag = FALSE;
SxTxnCreationData *creation_data;
creation_data = (SxTxnCreationData*)user_data;
SxTxnCreationData *creation_data = (SxTxnCreationData*)user_data;
SchedXaction *sx = creation_data->instance->parent->sx;
/* FIXME: In general, this should [correctly] deal with errors such
as not finding the approrpiate Accounts and not being able to
@ -1024,9 +1111,10 @@ create_each_transaction_helper(Transaction *template_txn, void *user_data)
g_debug("creating template txn desc [%s] for sx [%s]",
xaccTransGetDescription(new_txn),
xaccSchedXactionGetName(creation_data->instance->parent->sx));
xaccSchedXactionGetName(sx));
g_debug("template txn currency is %s", gnc_commodity_get_mnemonic(xaccTransGetCurrency (template_txn)));
g_debug("template txn currency is %s",
gnc_commodity_get_mnemonic(xaccTransGetCurrency (template_txn)));
/* Bug#500427: copy the notes, if any */
if (xaccTransGetNotes(template_txn) != NULL)
@ -1044,15 +1132,15 @@ create_each_transaction_helper(Transaction *template_txn, void *user_data)
if ((template_splits == NULL) || (txn_splits == NULL))
{
g_critical("transaction w/o splits for sx [%s]",
xaccSchedXactionGetName(creation_data->instance->parent->sx));
xaccSchedXactionGetName(sx));
xaccTransDestroy(new_txn);
xaccTransCommitEdit(new_txn);
return FALSE;
}
for (;
txn_splits && template_splits;
txn_splits = txn_splits->next, template_splits = template_splits->next)
txn_splits && template_splits;
txn_splits = txn_splits->next, template_splits = template_splits->next)
{
const Split *template_split;
Account *split_acct;
@ -1064,7 +1152,8 @@ create_each_transaction_helper(Transaction *template_txn, void *user_data)
template_split = (Split*)template_splits->data;
copying_split = (Split*)txn_splits->data;
if (!_get_template_split_account(creation_data->instance->parent->sx, template_split, &split_acct, creation_data->creation_errors))
if (!_get_template_split_account(sx, template_split, &split_acct,
creation_data->creation_errors))
{
err_flag = TRUE;
break;
@ -1073,108 +1162,35 @@ create_each_transaction_helper(Transaction *template_txn, void *user_data)
split_cmdty = xaccAccountGetCommodity(split_acct);
if (first_cmdty == NULL)
{
/* Set new_txn currency to template_txn if we have one, else first split */
/* Set new_txn currency to template_txn if we have one, else first
* split
*/
if (xaccTransGetCurrency(template_txn))
xaccTransSetCurrency(new_txn, xaccTransGetCurrency(template_txn));
else
xaccTransSetCurrency(new_txn,
xaccTransGetCurrency(template_txn));
else /* FIXME check for marker split */
xaccTransSetCurrency(new_txn, split_cmdty);
first_cmdty = xaccTransGetCurrency(new_txn);
}
g_debug("new txn currency is %s", gnc_commodity_get_mnemonic(first_cmdty));
g_debug("new txn currency is %s",
gnc_commodity_get_mnemonic(first_cmdty));
xaccSplitSetAccount(copying_split, split_acct);
{
gnc_numeric credit_num, debit_num, final;
gint gncn_error;
credit_num = gnc_numeric_zero();
debit_num = gnc_numeric_zero();
_get_credit_formula_value(creation_data->instance, template_split, &credit_num, creation_data->creation_errors);
_get_debit_formula_value(creation_data->instance, template_split, &debit_num, creation_data->creation_errors);
final = gnc_numeric_sub_fixed( debit_num, credit_num );
gncn_error = gnc_numeric_check(final);
if (gncn_error != GNC_ERROR_OK)
{
GString *err = g_string_new("");
g_string_printf(err, "error %d in SX [%s] final gnc_numeric value, using 0 instead",
gncn_error, xaccSchedXactionGetName(creation_data->instance->parent->sx));
g_critical("%s", err->str);
if (creation_data->creation_errors != NULL)
*creation_data->creation_errors = g_list_append(*creation_data->creation_errors, err);
else
g_string_free(err, TRUE);
final = gnc_numeric_zero();
}
gnc_numeric final = split_apply_formulas(template_split,
creation_data);
xaccSplitSetValue(copying_split, final);
g_debug("value is %s for memo split '%s'", gnc_numeric_to_string (final), xaccSplitGetMemo (copying_split));
if (! gnc_commodity_equal(split_cmdty, xaccTransGetCurrency (new_txn)))
g_debug("value is %s for memo split '%s'",
gnc_numeric_to_string (final),
xaccSplitGetMemo (copying_split));
if (! gnc_commodity_equal(split_cmdty,
xaccTransGetCurrency (new_txn)))
{
GString *exchange_rate_var_name = g_string_sized_new(16);
GncSxVariable *exchange_rate_var;
gnc_numeric exchange_rate, amt;
/*
GNCPriceDB *price_db = gnc_pricedb_get_db(gnc_get_current_book());
GNCPrice *price;
price = gnc_pricedb_lookup_latest(price_db, first_cmdty, split_cmdty);
if (price == NULL)
{
GString *err = g_string_new("");
g_string_printf(err, "could not find pricedb entry for commodity-pair (%s, %s).",
gnc_commodity_get_mnemonic(first_cmdty),
gnc_commodity_get_mnemonic(split_cmdty));
exchange = gnc_numeric_create(1, 1);
*creation_data->creation_errors = g_list_append(*creation_data->creation_errors, err);
}
else
{
if (gnc_commodity_equiv(first_cmdty,
gnc_price_get_commodity(price)))
exchange = gnc_numeric_invert(gnc_price_get_value(price));
exchange = gnc_numeric_convert(exchange, 1000,
GNC_HOW_RND_ROUND_HALF_UP);
}
}
else
{
exchange = gnc_price_get_value(price);
}
*/
exchange_rate = gnc_numeric_create (1, 1);
g_string_printf(exchange_rate_var_name, "%s -> %s",
gnc_commodity_get_mnemonic(first_cmdty),
gnc_commodity_get_mnemonic(split_cmdty));
g_debug("var_name is %s -> %s", gnc_commodity_get_mnemonic(first_cmdty),
gnc_commodity_get_mnemonic(split_cmdty));
exchange_rate_var = (GncSxVariable*)g_hash_table_lookup(creation_data->instance->variable_bindings,
exchange_rate_var_name->str);
if (exchange_rate_var != NULL)
{
exchange_rate = exchange_rate_var->value;
g_debug("exchange_rate is %s", gnc_numeric_to_string (exchange_rate));
}
g_string_free(exchange_rate_var_name, TRUE);
if (!gnc_commodity_is_currency (split_cmdty))
amt = gnc_numeric_div(final, exchange_rate, gnc_commodity_get_fraction (split_cmdty), GNC_HOW_RND_ROUND_HALF_UP);
else
amt = gnc_numeric_mul(final, exchange_rate, 1000, GNC_HOW_RND_ROUND_HALF_UP);
g_debug("amount is %s for memo split '%s'", gnc_numeric_to_string (amt), xaccSplitGetMemo (copying_split));
xaccSplitSetAmount(copying_split, amt); /* marks split dirty */
split_apply_exchange_rate(copying_split,
creation_data->instance->variable_bindings,
first_cmdty, split_cmdty, &final);
}
xaccSplitScrub(copying_split);
@ -1184,7 +1200,7 @@ create_each_transaction_helper(Transaction *template_txn, void *user_data)
if (err_flag)
{
g_critical("new transaction creation sx [%s]",
xaccSchedXactionGetName(creation_data->instance->parent->sx));
xaccSchedXactionGetName(sx));
xaccTransDestroy(new_txn);
xaccTransCommitEdit(new_txn);
return FALSE;
@ -1202,7 +1218,8 @@ create_each_transaction_helper(Transaction *template_txn, void *user_data)
if (creation_data->created_txn_guids != NULL)
{
*creation_data->created_txn_guids
= g_list_append(*(creation_data->created_txn_guids), (gpointer)xaccTransGetGUID(new_txn));
= g_list_append(*(creation_data->created_txn_guids),
(gpointer)xaccTransGetGUID(new_txn));
}
return FALSE;
@ -1273,41 +1290,42 @@ gnc_sx_instance_model_effect_change(GncSxInstanceModel *model,
}
if (inst->orig_state == SX_INSTANCE_STATE_POSTPONED
&& inst->state != SX_INSTANCE_STATE_POSTPONED)
&& inst->state != SX_INSTANCE_STATE_POSTPONED)
{
// remove from postponed list
g_assert(inst->temporal_state != NULL);
gnc_sx_remove_defer_instance(inst->parent->sx, inst->temporal_state);
gnc_sx_remove_defer_instance(inst->parent->sx,
inst->temporal_state);
}
switch (inst->state)
{
case SX_INSTANCE_STATE_CREATED:
// nop: we've already processed this.
break;
case SX_INSTANCE_STATE_IGNORED:
increment_sx_state(inst, &last_occur_date, &instance_count, &remain_occur_count);
break;
case SX_INSTANCE_STATE_POSTPONED:
if (inst->orig_state != SX_INSTANCE_STATE_POSTPONED)
{
gnc_sx_add_defer_instance(instances->sx,
gnc_sx_clone_temporal_state (inst->temporal_state));
}
increment_sx_state(inst, &last_occur_date, &instance_count, &remain_occur_count);
break;
case SX_INSTANCE_STATE_TO_CREATE:
create_transactions_for_instance(inst, created_transaction_guids, creation_errors);
increment_sx_state(inst, &last_occur_date, &instance_count, &remain_occur_count);
gnc_sx_instance_model_change_instance_state(model, inst, SX_INSTANCE_STATE_CREATED);
break;
case SX_INSTANCE_STATE_REMINDER:
// do nothing
// assert no non-remind instances after this?
break;
default:
g_assert_not_reached();
break;
case SX_INSTANCE_STATE_CREATED:
// nop: we've already processed this.
break;
case SX_INSTANCE_STATE_IGNORED:
increment_sx_state(inst, &last_occur_date, &instance_count, &remain_occur_count);
break;
case SX_INSTANCE_STATE_POSTPONED:
if (inst->orig_state != SX_INSTANCE_STATE_POSTPONED)
{
gnc_sx_add_defer_instance(instances->sx,
gnc_sx_clone_temporal_state (inst->temporal_state));
}
increment_sx_state(inst, &last_occur_date, &instance_count, &remain_occur_count);
break;
case SX_INSTANCE_STATE_TO_CREATE:
create_transactions_for_instance(inst, created_transaction_guids, creation_errors);
increment_sx_state(inst, &last_occur_date, &instance_count, &remain_occur_count);
gnc_sx_instance_model_change_instance_state(model, inst, SX_INSTANCE_STATE_CREATED);
break;
case SX_INSTANCE_STATE_REMINDER:
// do nothing
// assert no non-remind instances after this?
break;
default:
g_assert_not_reached();
break;
}
}
@ -1319,8 +1337,8 @@ gnc_sx_instance_model_effect_change(GncSxInstanceModel *model,
void
gnc_sx_instance_model_change_instance_state(GncSxInstanceModel *model,
GncSxInstance *instance,
GncSxInstanceState new_state)
GncSxInstance *instance,
GncSxInstanceState new_state)
{
if (instance->state == new_state)
return;
@ -1461,8 +1479,8 @@ gnc_sx_instance_model_summarize(GncSxInstanceModel *model, GncSxSummary *summary
// if all the instances are 'auto-create, no-notify', then we don't need
// the dialog.
summary->need_dialog
= (summary->num_instances != 0
&& summary->num_auto_create_no_notify_instances != summary->num_instances);
= (summary->num_instances != 0
&& summary->num_auto_create_no_notify_instances != summary->num_instances);
}
void
@ -1575,8 +1593,8 @@ create_cashflow_helper(Transaction *template_txn, void *user_data)
}
for (;
template_splits;
template_splits = template_splits->next)
template_splits;
template_splits = template_splits->next)
{
Account *split_acct;
const gnc_commodity *split_cmdty = NULL;

View File

@ -101,7 +101,7 @@ typedef struct _GncSxVariable
typedef struct _GncSxInstance
{
GncSxInstances *parent; /**< the parent instances collection. **/
void *temporal_state; /**< the sx creation temporal state. **/
SXTmpStateData *temporal_state; /**< the sx creation temporal state. **/
GncSxInstanceState orig_state; /**< the original state at generation time. **/
GncSxInstanceState state; /**< the current state of the instance (during editing) **/
GDate date; /**< the instance date. **/

View File

@ -2699,7 +2699,6 @@ InvoiceWindow * gnc_ui_invoice_duplicate (GncInvoice *old_invoice, gboolean open
{
InvoiceWindow *iw;
GncInvoice *new_invoice = NULL;
gchar *new_id;
GDate new_date_gdate;
g_assert(old_invoice);
@ -2720,11 +2719,8 @@ InvoiceWindow * gnc_ui_invoice_duplicate (GncInvoice *old_invoice, gboolean open
}
}
// Set a new id from the respective counter
new_id = gncInvoiceNextID(gnc_get_current_book(),
gncInvoiceGetOwner(new_invoice));
gncInvoiceSetID(new_invoice, new_id);
g_free(new_id);
// Unset the invoice ID, let it get allocated later
gncInvoiceSetID(new_invoice, "");
// Modify the date to today
if (new_date)

View File

@ -605,19 +605,19 @@ gnc_plugin_page_owner_tree_create_widget (GncPluginPage *plugin_page)
case GNC_OWNER_UNDEFINED :
break;
case GNC_OWNER_CUSTOMER :
label = N_("Customers");
label = _("Customers");
state_section = "Customers Overview";
break;
case GNC_OWNER_JOB :
label = N_("Jobs");
label = _("Jobs");
state_section = "Jobs Overview";
break;
case GNC_OWNER_VENDOR :
label = N_("Vendors");
label = _("Vendors");
state_section = "Vendors Overview";
break;
case GNC_OWNER_EMPLOYEE :
label = N_("Employees");
label = _("Employees");
state_section = "Employees Overview";
break;
}

View File

@ -86,7 +86,7 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xpad">8</property>
<property name="label" translatable="yes">Dummy message</property>
<property name="label" translatable="no">Dummy message</property>
</object>
<packing>
<property name="expand">True</property>
@ -128,7 +128,7 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">postd</property>
<property name="label" translatable="no">postdate</property>
<property name="justify">right</property>
</object>
<packing>
@ -142,7 +142,7 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">duedate</property>
<property name="label" translatable="no">duedate</property>
<property name="justify">right</property>
</object>
<packing>
@ -156,7 +156,7 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">Description</property>
<property name="label" translatable="Yes">Description</property>
<property name="justify">right</property>
</object>
<packing>
@ -170,7 +170,7 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">acct</property>
<property name="label" translatable="no">acct</property>
<property name="justify">right</property>
</object>
<packing>
@ -264,7 +264,7 @@
</child>
<child>
<object class="GtkCheckButton" id="question_check">
<property name="label" translatable="yes">question</property>
<property name="label" translatable="no">question</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">False</property>
@ -405,7 +405,7 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xpad">8</property>
<property name="label" translatable="yes">Dummy message</property>
<property name="label" translatable="no">Dummy message</property>
</object>
<packing>
<property name="expand">True</property>
@ -442,7 +442,7 @@
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">1</property>
<property name="label" translatable="yes">label</property>
<property name="label" translatable="no">label</property>
</object>
<packing>
<property name="expand">False</property>

View File

@ -152,7 +152,7 @@
<child>
<object class="GtkEntry" id="page_id_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_focus">False</property>
<property name="editable">False</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
@ -196,7 +196,7 @@
<child>
<object class="GtkEntry" id="acct_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_focus">False</property>
<property name="editable">False</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
@ -387,7 +387,7 @@
<child>
<object class="GtkEntry" id="page_billing_id_entry">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_focus">False</property>
<property name="editable">False</property>
<property name="primary_icon_activatable">False</property>
<property name="secondary_icon_activatable">False</property>
@ -403,7 +403,7 @@
<child>
<object class="GtkEntry" id="page_terms_menu">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="can_focus">False</property>
<property name="editable">False</property>
<property name="invisible_char">●</property>
<property name="primary_icon_activatable">False</property>

View File

@ -540,7 +540,7 @@ In case of an over-payment or if no invoice was selected, GnuCash will automatic
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="xalign">0</property>
<property name="label" translatable="yes">(USD)</property>
<property name="label" translatable="no">(USD)</property>
</object>
<packing>
<property name="left_attach">1</property>

View File

@ -870,105 +870,22 @@ xaccSchedXactionSetAdvanceReminder( SchedXaction *sx, gint reminderDays )
gnc_sx_commit_edit(sx);
}
GDate
xaccSchedXactionGetNextInstance(const SchedXaction *sx, SXTmpStateData *stateData )
{
GDate last_occur, next_occur, tmpDate;
g_date_clear( &last_occur, 1 );
g_date_clear( &next_occur, 1 );
g_date_clear( &tmpDate, 1 );
if ( g_date_valid( &sx->last_date ) )
{
last_occur = sx->last_date;
}
if ( stateData != NULL )
{
SXTmpStateData *tsd = (SXTmpStateData*)stateData;
last_occur = tsd->last_date;
}
if ( g_date_valid( &sx->start_date ) )
{
if ( g_date_valid(&last_occur) )
{
last_occur =
( g_date_compare( &last_occur,
&sx->start_date ) > 0 ?
last_occur : sx->start_date );
}
else
{
/* Think about this for a second, and you realize that if the
* start date is _today_, we need a last-occur date such that
* the 'next instance' is after that date, and equal to the
* start date... one day should be good.
*
* This only holds for the first instance [read: if the
* last[-occur]_date is invalid] */
last_occur = sx->start_date;
g_date_subtract_days( &last_occur, 1 );
}
}
recurrenceListNextInstance(sx->schedule, &last_occur, &next_occur);
/* out-of-bounds check */
if ( xaccSchedXactionHasEndDate( sx ) )
{
const GDate *end_date = xaccSchedXactionGetEndDate( sx );
if ( g_date_compare( &next_occur, end_date ) > 0 )
{
g_debug("next_occur past end date");
g_date_clear( &next_occur, 1 );
}
}
else if ( xaccSchedXactionHasOccurDef( sx ) )
{
if ( stateData )
{
SXTmpStateData *tsd = (SXTmpStateData*)stateData;
if ( tsd->num_occur_rem == 0 )
{
g_debug("no more occurances remain");
g_date_clear( &next_occur, 1 );
}
}
else
{
if ( sx->num_occurances_remain == 0 )
{
g_date_clear( &next_occur, 1 );
}
}
}
return next_occur;
}
GDate
xaccSchedXactionGetInstanceAfter( const SchedXaction *sx,
GDate *date,
SXTmpStateData *stateData )
xaccSchedXactionGetNextInstance (const SchedXaction *sx, SXTmpStateData *tsd)
{
GDate prev_occur, next_occur;
g_date_clear( &prev_occur, 1 );
if ( date )
{
prev_occur = *date;
}
if ( stateData != NULL )
{
SXTmpStateData *tsd = (SXTmpStateData*)stateData;
if ( tsd != NULL )
prev_occur = tsd->last_date;
}
if ( ! g_date_valid( &prev_occur ) )
/* If prev_occur is in the "cleared" state and sx->start_date isn't, then
* we're at the beginning. We want to pretend prev_occur is the day before
* the start_date in case the start_date is today so that the SX will fire
* today. If start_date isn't valid either then the SX will fire anyway, no
* harm done.
*/
if (! g_date_valid( &prev_occur ) && g_date_valid(&sx->start_date))
{
/* We must be at the beginning. */
prev_occur = sx->start_date;
@ -987,20 +904,10 @@ xaccSchedXactionGetInstanceAfter( const SchedXaction *sx,
}
else if ( xaccSchedXactionHasOccurDef( sx ) )
{
if ( stateData )
if ((tsd && tsd->num_occur_rem == 0) ||
(!tsd && sx->num_occurances_remain == 0 ))
{
SXTmpStateData *tsd = (SXTmpStateData*)stateData;
if ( tsd->num_occur_rem == 0 )
{
g_date_clear( &next_occur, 1 );
}
}
else
{
if ( sx->num_occurances_remain == 0 )
{
g_date_clear( &next_occur, 1 );
}
g_date_clear( &next_occur, 1 );
}
}
return next_occur;
@ -1142,45 +1049,36 @@ gnc_sx_create_temporal_state(const SchedXaction *sx )
}
void
gnc_sx_incr_temporal_state(const SchedXaction *sx, SXTmpStateData *stateData )
gnc_sx_incr_temporal_state(const SchedXaction *sx, SXTmpStateData *tsd )
{
GDate unused;
SXTmpStateData *tsd = (SXTmpStateData*)stateData;
g_date_clear( &unused, 1 );
tsd->last_date =
xaccSchedXactionGetInstanceAfter( sx,
&unused,
stateData );
if ( xaccSchedXactionHasOccurDef( sx ) )
g_return_if_fail(tsd != NULL);
tsd->last_date = xaccSchedXactionGetNextInstance (sx, tsd);
if (xaccSchedXactionHasOccurDef (sx))
{
tsd->num_occur_rem -= 1;
--tsd->num_occur_rem;
}
tsd->num_inst += 1;
++tsd->num_inst;
}
void
gnc_sx_destroy_temporal_state( SXTmpStateData *stateData )
gnc_sx_destroy_temporal_state (SXTmpStateData *tsd)
{
g_free( (SXTmpStateData*)stateData );
g_free(tsd);
}
SXTmpStateData*
gnc_sx_clone_temporal_state( SXTmpStateData *stateData )
gnc_sx_clone_temporal_state (SXTmpStateData *tsd)
{
SXTmpStateData *toRet, *tsd;
tsd = (SXTmpStateData*)stateData;
toRet = g_memdup( tsd, sizeof( SXTmpStateData ) );
SXTmpStateData *toRet;
toRet = g_memdup (tsd, sizeof (SXTmpStateData));
return toRet;
}
static
gint
static gint
_temporal_state_data_cmp( gconstpointer a, gconstpointer b )
{
SXTmpStateData *tsd_a, *tsd_b;
tsd_a = (SXTmpStateData*)a;
tsd_b = (SXTmpStateData*)b;
const SXTmpStateData *tsd_a = (SXTmpStateData*)a;
const SXTmpStateData *tsd_b = (SXTmpStateData*)b;
if ( !tsd_a && !tsd_b )
return 0;
@ -1207,8 +1105,8 @@ gnc_sx_add_defer_instance( SchedXaction *sx, void *deferStateData )
}
/**
* Removes an instance from the deferred list. If the instance is no longer
* useful; gnc_sx_destroy_temporal_state() it.
* Removes an instance from the deferred list. The saved SXTmpStateData existed
* for comparison only, so destroy it.
**/
void
gnc_sx_remove_defer_instance( SchedXaction *sx, void *deferStateData )

View File

@ -269,10 +269,8 @@ SXTmpStateData *gnc_sx_clone_temporal_state( SXTmpStateData *stateData );
* for possible action without modifying the SX state until action is
* actually taken.
*/
GDate xaccSchedXactionGetNextInstance(const SchedXaction *sx, SXTmpStateData *stateData );
GDate xaccSchedXactionGetInstanceAfter(const SchedXaction *sx,
GDate *date,
SXTmpStateData *stateData );
GDate xaccSchedXactionGetNextInstance(const SchedXaction *sx,
SXTmpStateData *stateData);
/** \brief Set the schedxaction's template transaction.

View File

@ -258,7 +258,7 @@ SCM_FILE_LINKS = \
${gncscm_DATA}
endif
.scm-links:
.scm-links:
$(RM) -rf gnucash
mkdir -p gnucash
if GNUCASH_SEPARATE_BUILDDIR
@ -311,8 +311,9 @@ CLEANFILES = \
MAINTAINERCLEANFILES = swig-gnome-utils.c
# FIXME: Symlinking directories only works on non-win32.
# We want to do this only for the Gnome help tool on Linux and MacPorts.
if !PLATFORM_WIN32
if !PLATFORM_OSX_QUARTZ
#
# I hate inconsistent standards. Autotools puts help files into
# ${datadir}/gnome/help/${program} while the gnome2 libraries expect
@ -324,5 +325,6 @@ install-data-hook:
uninstall-hook:
rm -f ${DESTDIR}${pkgdatadir}/gnome
endif
endif
AM_CPPFLAGS += -DG_LOG_DOMAIN=\"gnc.gui\"

View File

@ -4371,7 +4371,7 @@ gnc_main_window_cmd_help_about (GtkAction *action, GncMainWindow *window)
{
const gchar *fixed_message = _("The GnuCash personal finance manager. "
"The GNU way to manage your money!");
const gchar *copyright = _("© 1997-2015 Contributors");
const gchar *copyright = _("© 1997-2016 Contributors");
gchar **authors = get_file_strsplit("AUTHORS");
gchar **documenters = get_file_strsplit("DOCUMENTERS");
gchar *license = get_file("LICENSE");

File diff suppressed because it is too large Load Diff

View File

@ -383,7 +383,10 @@ load_txf_info (gint acct_category, TaxInfoDialog *ti_dialog)
line = g_strdup ("");
temp2 = g_strdup_printf ("%d", line_year);
temp = g_strconcat (form_line_data, "\n", temp2, " - ",
until, " ", line, NULL);
((year != 0) && (until == now))
? g_strdup_printf("%d", year)
: until,
" ", line, NULL);
if (until != now)
g_free (until);
until = g_strdup_printf ("%d", (line_year - 1));

View File

@ -576,26 +576,63 @@
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment5">
<object class="GtkVPaned" id="vpaned1">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="left_padding">12</property>
<property name="can_focus">True</property>
<child>
<object class="GtkScrolledWindow" id="scrolledwindow28">
<object class="GtkAlignment" id="alignment5">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hscrollbar_policy">automatic</property>
<property name="vscrollbar_policy">automatic</property>
<property name="shadow_type">in</property>
<property name="left_padding">12</property>
<child>
<object class="GtkTreeView" id="txf_category_view">
<object class="GtkScrolledWindow" id="scrolledwindow28">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="reorderable">True</property>
<property name="rules_hint">True</property>
<property name="can_focus">False</property>
<property name="hscrollbar_policy">automatic</property>
<property name="vscrollbar_policy">automatic</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkTreeView" id="txf_category_view">
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="reorderable">True</property>
<property name="rules_hint">True</property>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="resize">True</property>
<property name="shrink">True</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="left_padding">12</property>
<child>
<object class="GtkScrolledWindow" id="help_scroll">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hscrollbar_policy">automatic</property>
<property name="vscrollbar_policy">automatic</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkTextView" id="txf_help_text">
<property name="can_focus">False</property>
<property name="editable">False</property>
<property name="wrap_mode">word</property>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="resize">False</property>
<property name="shrink">True</property>
</packing>
</child>
</object>
<packing>
@ -604,34 +641,6 @@
<property name="position">1</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment6">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="left_padding">12</property>
<child>
<object class="GtkScrolledWindow" id="help_scroll">
<property name="visible">True</property>
<property name="can_focus">False</property>
<property name="hscrollbar_policy">automatic</property>
<property name="vscrollbar_policy">automatic</property>
<property name="shadow_type">in</property>
<child>
<object class="GtkTextView" id="txf_help_text">
<property name="can_focus">False</property>
<property name="editable">False</property>
<property name="wrap_mode">word</property>
</object>
</child>
</object>
</child>
</object>
<packing>
<property name="expand">False</property>
<property name="fill">False</property>
<property name="position">2</property>
</packing>
</child>
</object>
<packing>
<property name="expand">True</property>

View File

@ -74,8 +74,9 @@ EXTRA_DIST = \
CLEANFILES = $(BUILT_SOURCES) gnucash
MAINTAINERCLEANFILES = swig-gnc-html.c
# FIXME: Symlinking directories only works on non-win32.
# We do this only for the gnome help tool on Linux and MacPorts.
if !PLATFORM_WIN32
if !PLATFORM_OSX_QUARTZ
#
# I hate inconsistent standards. Autotools puts help files into
# ${datadir}/gnome/help/${program} while the gnome2 libraries expect
@ -87,5 +88,6 @@ install-data-hook:
uninstall-hook:
rm -f ${DESTDIR}${pkgdatadir}/gnome
endif
endif
AM_CPPFLAGS += -DG_LOG_DOMAIN=\"gnc.html\"

View File

@ -582,7 +582,8 @@ ab_account_longname(const AB_ACCOUNT *ab_acc)
bankcode = AB_Account_GetBankCode(ab_acc);
subAccountId = AB_Account_GetSubAccountId(ab_acc);
/* Translators: Strings are 1. Account code, 2. Bank name, 3. Bank code. */
/* Translators: Strings are 1. Bank code, 2. Bank name,
* 3. Account Number, 4. Subaccount ID */
result = g_strdup_printf(_("Bank code %s (%s), Account %s (%s)"),
bankcode,
bankname ? bankname : "",

View File

@ -191,6 +191,7 @@ struct _qifimportwindow
SCM match_transactions;
SCM transaction_status;
int selected_transaction;
gchar *date_format;
};
struct _qifassistantpage
@ -1812,6 +1813,7 @@ gnc_ui_qif_import_load_progress_start_cb(GtkButton * button,
parse_return = scm_call_2(qif_file_parse, SCM_CAR(imported_files), progress);
gnc_progress_dialog_pop(wind->load_progress);
wind->ask_date_format = FALSE;
wind->date_format = NULL;
if (parse_return == SCM_BOOL_T)
{
/* Canceled by the user. */
@ -2007,28 +2009,31 @@ gnc_ui_qif_import_date_valid_cb (GtkWidget *widget, gpointer user_data)
gint num = gtk_assistant_get_current_page (assistant);
GtkWidget *page = gtk_assistant_get_nth_page (assistant, num);
SCM reparse_dates = scm_c_eval_string("qif-file:reparse-dates");
SCM format_sym;
gchar *text;
/* Get the selected date format. */
model = gtk_combo_box_get_model(GTK_COMBO_BOX(wind->date_format_combo));
gtk_combo_box_get_active_iter (GTK_COMBO_BOX(wind->date_format_combo), &iter);
gtk_tree_model_get( model, &iter, 0, &text, -1 );
model = gtk_combo_box_get_model(GTK_COMBO_BOX (wind->date_format_combo));
gtk_combo_box_get_active_iter (GTK_COMBO_BOX (wind->date_format_combo), &iter);
gtk_tree_model_get (model, &iter, 0, &wind->date_format, -1);
if (!text)
if (!wind->date_format)
{
g_critical("QIF import: BUG DETECTED in gnc_ui_qif_import_date_valid_cb. Format is NULL.");
}
format_sym = scm_from_locale_symbol (text);
g_free(text);
/* Reparse the dates using the selected format. */
scm_call_2(reparse_dates, wind->selected_file, format_sym);
gtk_assistant_set_page_complete (assistant, page, TRUE);
}
static void
qif_import_reparse_dates (QIFImportWindow* wind)
{
SCM reparse_dates = scm_c_eval_string ("qif-file:reparse-dates");
SCM format_sym = scm_from_locale_symbol (wind->date_format);
/* Reparse the dates using the selected format. */
scm_call_2 (reparse_dates, wind->selected_file, format_sym);
g_free (wind->date_format);
wind->date_format = NULL;
wind->ask_date_format = FALSE;
}
/******************************************
* Page 4 - Account Setup Page Procedures
@ -2046,8 +2051,9 @@ gnc_ui_qif_import_account_prepare (GtkAssistant *assistant, gpointer user_data)
gint num = gtk_assistant_get_current_page (assistant);
SCM check_from_acct = scm_c_eval_string("qif-file:check-from-acct");
/* Determine the next page to display. */
if (wind->ask_date_format && wind->date_format)
qif_import_reparse_dates (wind);
/* Determine the next page to display. */
if (scm_call_1(check_from_acct, wind->selected_file) != SCM_BOOL_T)
{
/* There is an account name missing. Ask the user to provide one. */

View File

@ -898,7 +898,7 @@
(let loop ((current (car objects))
(rest (cdr objects)))
(let ((val (getter current)))
(if (and val (string? val))
(if val
(begin
(set! do-parsing #t)
(set! formats (checker val formats))))

View File

@ -419,7 +419,7 @@
(let ((retval '()))
(if (or (not (string? date-string))
(not (> (string-length date-string) 0)))
(set! retval possible-formats)
(set! retval #f)
(let ((match (regexp-exec qif-date-compiled-rexp date-string)))
(if match
(if (match:substring match 1)

View File

@ -80,6 +80,8 @@
#include "gncIDSearch.h"
#include "engine/gnc-pricedb.h"
#include "app-utils/gnc-prefs-utils.h"
#include "cap-gains.h"
#include "Scrub3.h"
%}
%include <timespec.i>
@ -210,6 +212,9 @@ static const GncGUID * gncEntryGetGUID(GncEntry *x);
// Commodity prices includes and stuff
%include <gnc-pricedb.h>
%include <cap-gains.h>
%include <Scrub3.h>
%init %{
gnc_environment_setup();
qof_log_init();

View File

@ -1,6 +1,7 @@
from unittest import main
from gnucash import Book, Account, Split
from datetime import datetime
from gnucash import Book, Account, Split, GncCommodity, GncNumeric, \
Transaction
from test_book import BookSession
@ -21,5 +22,49 @@ class TestAccount( AccountSession ):
self.assertTrue(self.account.insert_split(SPLIT))
self.assertTrue(self.account.remove_split(SPLIT))
def test_assignlots(self):
abc = GncCommodity(self.book, 'ABC Fund',
'COMMODITY','ABC','ABC',100000)
self.table.insert(abc)
self.account.SetCommodity(abc)
other = Account(self.book)
other.SetCommodity(self.currency)
tx = Transaction(self.book)
tx.BeginEdit()
tx.SetCurrency(self.currency)
tx.SetDateEnteredTS(datetime.now())
tx.SetDatePostedTS(datetime.now())
s1a = Split(self.book)
s1a.SetParent(tx)
s1a.SetAccount(self.account)
s1a.SetAmount(GncNumeric(1.0))
s1a.SetValue(GncNumeric(100.0))
s1b = Split(self.book)
s1b.SetParent(tx)
s1b.SetAccount(other)
s1b.SetAmount(GncNumeric(-100.0))
s1b.SetValue(GncNumeric(-100.0))
s2a = Split(self.book)
s2a.SetParent(tx)
s2a.SetAccount(self.account)
s2a.SetAmount(GncNumeric(-0.5))
s2a.SetValue(GncNumeric(-100.0))
s2b = Split(self.book)
s2b.SetParent(tx)
s2b.SetAccount(other)
s2b.SetAmount(GncNumeric(100.0))
s2b.SetValue(GncNumeric(100.0))
tx.CommitEdit()
self.account.ScrubLots()
self.assertEqual(len(self.account.GetLotList()),1)
if __name__ == '__main__':
main()

View File

@ -6,8 +6,8 @@ class BookSession( TestCase ):
def setUp(self):
self.ses = Session()
self.book = self.ses.get_book()
table = self.book.get_table()
self.currency = table.lookup('CURRENCY', 'EUR')
self.table = self.book.get_table()
self.currency = self.table.lookup('CURRENCY', 'EUR')
class TestBook( BookSession ):
def test_markclosed(self):

View File

@ -697,10 +697,11 @@ gnc_template_register_save_debcred_cell (BasicCell * cell,
{
SRSaveData *sd = save_data;
SplitRegister *reg = user_data;
const char *credit_formula, *debit_formula;
const char *formula;
char *error_loc;
gnc_numeric credit_amount, debit_amount;
gnc_numeric amount;
gboolean parse_result;
GHashTable *parser_vars = g_hash_table_new(g_str_hash, g_str_equal);
g_return_if_fail (gnc_basic_cell_has_name (cell, FDEBT_CELL) ||
gnc_basic_cell_has_name (cell, FCRED_CELL));
@ -710,35 +711,50 @@ gnc_template_register_save_debcred_cell (BasicCell * cell,
/* amountStr = gnc_numeric_to_string (new_amount); */
credit_formula = gnc_table_layout_get_cell_value (reg->table->layout,
FCRED_CELL);
formula = gnc_table_layout_get_cell_value (reg->table->layout, FCRED_CELL);
/* If the value can be parsed into a numeric result (without any
* further variable definitions), store that numeric value
* additionally in the kvp. Otherwise store a zero numeric
* there.*/
parse_result = gnc_exp_parser_parse_separate_vars(credit_formula,
&credit_amount,
&error_loc, NULL);
if (!parse_result)
credit_amount = gnc_numeric_zero();
debit_formula = gnc_table_layout_get_cell_value (reg->table->layout,
FDEBT_CELL);
parse_result = gnc_exp_parser_parse_separate_vars(formula, &amount,
&error_loc, parser_vars);
if (g_hash_table_size(parser_vars) == 0)
{
if (!parse_result)
{
amount = gnc_numeric_zero();
}
qof_instance_set (QOF_INSTANCE (sd->split),
"sx-credit-numeric", amount,
NULL);
}
else
{
g_hash_table_destroy(parser_vars);
parser_vars = g_hash_table_new (g_str_hash, g_str_equal);
}
formula = gnc_table_layout_get_cell_value (reg->table->layout, FDEBT_CELL);
/* If the value can be parsed into a numeric result, store that
* numeric value additionally. See above comment.*/
parse_result = gnc_exp_parser_parse_separate_vars(debit_formula,
&debit_amount,
&error_loc, NULL);
if (!parse_result)
debit_amount = gnc_numeric_zero();
parse_result = gnc_exp_parser_parse_separate_vars(formula, &amount,
&error_loc, parser_vars);
if (parser_vars == NULL)
{
if (!parse_result)
{
amount = gnc_numeric_zero();
}
qof_instance_set (QOF_INSTANCE (sd->split),
"sx-debit-numeric", amount,
NULL);
}
else
{
g_hash_table_destroy(parser_vars);
parser_vars = NULL;
}
qof_instance_set (QOF_INSTANCE (sd->split),
"sx-credit-formula", credit_formula,
"sx-credit-numeric", &credit_amount,
"sx-debit-formula", debit_formula,
"sx-debit-numeric", &debit_amount,
NULL);
/* set the amount to an innocuous value */
/* Note that this marks the split dirty */
xaccSplitSetValue (sd->split, gnc_numeric_create (0, 1));

View File

@ -312,7 +312,7 @@ custom_report_delete (SCM guid, CustomReportDialog *crd)
report_name = gnc_scm_to_utf8_string(scm_call_2(template_menu_name, guid, SCM_BOOL_F));
/* we must confirm the user wants to delete their precious custom report! */
if (gnc_verify_dialog(crd->dialog, FALSE, "Are you sure you want to delete %s?", report_name))
if (gnc_verify_dialog(crd->dialog, FALSE, _("Are you sure you want to delete %s?"), report_name))
{
SCM del_report = scm_c_eval_string("gnc:delete-report");
scm_call_1(del_report, guid);