Implement user-entered-price preference.

Add user:price as a source and prefer values with lower PriceSource enum
values over higher ones: In other words a price with a lower PriceSource
value (e.g. user:price-editor) will overwrite one with a higher value (e.g.
user:split-register) and not the other way around.
This commit is contained in:
John Ralls 2015-09-09 15:06:56 -07:00
parent d9a0f311a4
commit 585cc4883f
4 changed files with 34 additions and 14 deletions

View File

@ -71,8 +71,12 @@ gnc_price_init(GNCPrice* price)
*/
static const char* source_names[] =
{
"user:price-editor", //sync with price_to_gui in dialog-price-editor.c
"Finance::Quote", //sync with
/* sync with price_to_gui in dialog-price-editor.c */
"user:price-editor",
/* sync with commidity-tz-quote->price in price-quotes.scm */
"Finance::Quote",
"user:price",
/* String retained for backwards compatibility. */
"user:xfer-dialog",
"user:split-register",
"user:stock-split",
@ -1004,7 +1008,7 @@ insert_or_replace_price(GNCPriceDB *db, GNCPrice *p)
p->currency, p->tmspec);
if (old_price == NULL)
return TRUE;
if (p->source != PRICE_SOURCE_FQ)
if (p->source < old_price->source)
return TRUE;
return FALSE;

View File

@ -165,7 +165,8 @@ typedef enum
{
PRICE_SOURCE_EDIT_DLG, // "user:price-editor"
PRICE_SOURCE_FQ, // "Finance::Quote"
PRICE_SOURCE_XFER_DLG, // "user:xfer-dialog"
PRICE_SOURCE_USER_PRICE, // "user:price"
PRICE_SOURCE_XFER_DLG_VAL, // "user:xfer-dialog"
PRICE_SOURCE_SPLIT_REG, // "user:split-register"
PRICE_SOURCE_STOCK_SPLIT, // "user:stock-split"
PRICE_SOURCE_INVOICE, // "user:invoice-post"
@ -174,7 +175,7 @@ typedef enum
#define PRICE_TYPE_LAST "last"
#define PRICE_TYPE_UNK "unknown"
#define PRICE_TYPE_TRN "transaction"
/* ------------------ */
/** @name Constructors
@{ */

View File

@ -121,6 +121,8 @@ struct _xferDialog
* creating a transaction)
*/
gnc_numeric *exch_rate;
PriceSource price_source;
const char *price_type;
/* Callback function to notify of the newly created Transaction */
gnc_xfer_dialog_cb transaction_cb;
@ -1058,6 +1060,9 @@ gnc_xfer_price_update_cb(GtkWidget *widget, GdkEventFocus *event,
XferDialog *xferData = data;
gnc_xfer_update_to_amount (xferData);
xferData->price_source = PRICE_SOURCE_USER_PRICE;
xferData->price_type = PRICE_TYPE_TRN;
return FALSE;
}
@ -1087,6 +1092,8 @@ gnc_xfer_to_amount_update_cb(GtkWidget *widget, GdkEventFocus *event,
price_value);
gnc_amount_edit_set_amount(GNC_AMOUNT_EDIT(xferData->price_edit),
price_value);
xferData->price_source = PRICE_SOURCE_XFER_DLG_VAL;
xferData->price_type = PRICE_TYPE_TRN;
gnc_xfer_dialog_update_conv_info(xferData);
return FALSE;
@ -1635,9 +1642,9 @@ create_price(XferDialog *xferData, Timespec ts)
gnc_price_unref (pr.price);
return;
}
if (gnc_price_get_source(pr.price) == PRICE_SOURCE_FQ)
if (gnc_price_get_source(pr.price) < xferData->price_source)
{
PINFO("Existing price is from Finance::Quote, so won't supersede.");
PINFO("Existing price is preferred, so won't supersede.");
gnc_price_unref (pr.price);
return;
}
@ -1650,7 +1657,8 @@ create_price(XferDialog *xferData, Timespec ts)
value = round_price(pr.from, pr.to, value);
gnc_price_begin_edit (pr.price);
gnc_price_set_time (pr.price, ts);
gnc_price_set_source (pr.price, PRICE_SOURCE_XFER_DLG);
gnc_price_set_source (pr.price, xferData->price_source);
gnc_price_set_typestr(pr.price, xferData->price_type);
gnc_price_set_value (pr.price, value);
gnc_price_commit_edit (pr.price);
PINFO("Modified price: 1 %s = %f %s",
@ -1683,7 +1691,8 @@ create_price(XferDialog *xferData, Timespec ts)
gnc_price_set_commodity (price, from);
gnc_price_set_currency (price, to);
gnc_price_set_time (price, ts);
gnc_price_set_source (price, PRICE_SOURCE_XFER_DLG);
gnc_price_set_source (price, xferData->price_source);
gnc_price_set_typestr (price, xferData->price_type);
gnc_price_set_value (price, value);
gnc_pricedb_add_price (xferData->pricedb, price);
gnc_price_commit_edit (price);

View File

@ -2044,7 +2044,8 @@ recalculate_value (Split *split, SplitRegister *reg,
}
static void
record_price (SplitRegister *reg, Account *account, gnc_numeric value)
record_price (SplitRegister *reg, Account *account, gnc_numeric value,
PriceSource source)
{
Transaction *trans = gnc_split_register_get_current_trans (reg);
QofBook *book = qof_instance_get_book (QOF_INSTANCE (account));
@ -2084,8 +2085,9 @@ record_price (SplitRegister *reg, Account *account, gnc_numeric value)
gnc_price_unref (price);
return;
}
if (gnc_price_get_source(price) == PRICE_SOURCE_FQ)
if (gnc_price_get_source(price) < PRICE_SOURCE_XFER_DLG_VAL)
{
/* Existing price is preferred over this one. */
gnc_price_unref(price);
return;
}
@ -2098,7 +2100,8 @@ record_price (SplitRegister *reg, Account *account, gnc_numeric value)
GNC_HOW_RND_ROUND_HALF_UP);
gnc_price_begin_edit (price);
gnc_price_set_time (price, ts);
gnc_price_set_source (price, PRICE_SOURCE_SPLIT_REG);
gnc_price_set_source (price, source);
gnc_price_set_typestr (price, PRICE_TYPE_TRN);
gnc_price_set_value (price, value);
gnc_price_commit_edit (price);
gnc_price_unref (price);
@ -2112,7 +2115,8 @@ record_price (SplitRegister *reg, Account *account, gnc_numeric value)
gnc_price_set_commodity (price, comm);
gnc_price_set_currency (price, curr);
gnc_price_set_time (price, ts);
gnc_price_set_source (price, PRICE_SOURCE_SPLIT_REG);
gnc_price_set_source (price, source);
gnc_price_set_typestr (price, PRICE_TYPE_TRN);
gnc_price_set_value (price, value);
gnc_pricedb_add_price (pricedb, price);
gnc_price_commit_edit (price);
@ -2135,6 +2139,7 @@ gnc_split_register_auto_calc (SplitRegister *reg, Split *split)
Account *account;
int denom;
int choice;
PriceSource source = PRICE_SOURCE_USER_PRICE;
if (STOCK_REGISTER != reg->type &&
CURRENCY_REGISTER != reg->type &&
@ -2283,6 +2288,7 @@ gnc_split_register_auto_calc (SplitRegister *reg, Split *split)
{
recalculate_price (split, reg, value, amount);
price_changed = TRUE;
source = PRICE_SOURCE_SPLIT_REG;
}
if (recalc_value)
recalculate_value (split, reg, price, amount, shares_changed);
@ -2293,7 +2299,7 @@ gnc_split_register_auto_calc (SplitRegister *reg, Split *split)
PRIC_CELL);
price = gnc_price_cell_get_value (cell);
if (gnc_numeric_positive_p(price))
record_price (reg, account, price);
record_price (reg, account, price, source);
}
return TRUE;
}