Exemplo n.º 1
0
static gint
default_sort (GNCPrice *price_a, GNCPrice *price_b)
{
    gnc_commodity *curr_a, *curr_b;
    Timespec ts_a, ts_b;
    gint result;

    /* Primary sort (i.e. commodity name) handled by the tree structure.  */

    /* secondary sort: currency */
    curr_a = gnc_price_get_currency (price_a);
    curr_b = gnc_price_get_currency (price_b);

    result = safe_utf8_collate (gnc_commodity_get_namespace (curr_a),
                                gnc_commodity_get_namespace (curr_b));
    if (result != 0) return result;

    result = safe_utf8_collate (gnc_commodity_get_mnemonic (curr_a),
                                gnc_commodity_get_mnemonic (curr_b));
    if (result != 0) return result;

    /* tertiary sort: time */
    ts_a = gnc_price_get_time (price_a);
    ts_b = gnc_price_get_time (price_b);
    result = timespec_cmp (&ts_a, &ts_b);
    if (result)
        /* Reverse the result to present the most recent quote first. */
        return -result;

    /* last sort: value */
    return gnc_numeric_compare (gnc_price_get_value (price_a),
                                gnc_price_get_value (price_b));
}
Exemplo n.º 2
0
/** Adds a split to a transaction.
 * @param trans The transaction to add a split to
 * @param account The split's account
 * @param amount The split's amount
 * @param rec_state The split's reconcile status
 * @param rec_date The split's reconcile date
 * @param price The split's conversion rate from account commodity to transaction commodity
 */
static void trans_add_split (Transaction* trans, Account* account, GncNumeric amount,
                            const boost::optional<std::string>& action,
                            const boost::optional<std::string>& memo,
                            const boost::optional<char>& rec_state,
                            const boost::optional<GncDate>& rec_date,
                            const boost::optional<GncNumeric> price)
{
    QofBook* book = xaccTransGetBook (trans);
    auto split = xaccMallocSplit (book);
    xaccSplitSetAccount (split, account);
    xaccSplitSetParent (split, trans);
    xaccSplitSetAmount (split, static_cast<gnc_numeric>(amount));
    auto trans_curr = xaccTransGetCurrency(trans);
    auto acct_comm = xaccAccountGetCommodity(account);
    GncNumeric value;
    if (gnc_commodity_equiv(trans_curr, acct_comm))
        value = amount;
    else if (price)
        value = amount * *price;
    else
    {
        auto time = xaccTransRetDatePosted (trans);
        /* Import data didn't specify price, let's lookup the nearest in time */
        auto nprice =
            gnc_pricedb_lookup_nearest_in_time64(gnc_pricedb_get_db(book),
                                                 acct_comm, trans_curr, time);
        if (nprice)
        {
            /* Found a usable price. Let's check if the conversion direction is right */
            GncNumeric rate;
            if (gnc_commodity_equiv(gnc_price_get_currency(nprice), trans_curr))
                rate = gnc_price_get_value(nprice);
            else
                rate = static_cast<GncNumeric>(gnc_price_get_value(nprice)).inv();

            value = amount * rate;
        }
        else
        {
            PWARN("No price found, using a price of 1.");
            value = amount;
        }
    }
    xaccSplitSetValue (split, static_cast<gnc_numeric>(value));

    if (memo)
        xaccSplitSetMemo (split, memo->c_str());
    /* Note, this function assumes the num/action switch is done at a higher level
     * if needed by the book option */
    if (action)
        xaccSplitSetAction (split, action->c_str());

    if (rec_state && *rec_state != 'n')
        xaccSplitSetReconcile (split, *rec_state);
    if (rec_state && *rec_state == YREC && rec_date)
        xaccSplitSetDateReconciledSecs (split,
                static_cast<time64>(GncDateTime(*rec_date, DayPart::neutral)));

}
static void
refresh_details_page (StockSplitInfo *info)
{
    GNCPrintAmountInfo print_info;
    gnc_commodity *commodity, *currency;
    Account *account;
    QofBook *book;
    GNCPriceDB *db;
    GList *prices;

    account = info->acct;

    g_return_if_fail (account != NULL);

    print_info = gnc_account_print_info (account, FALSE);

    gnc_amount_edit_set_print_info (GNC_AMOUNT_EDIT (info->distribution_edit),
                                    print_info);
    gnc_amount_edit_set_fraction (GNC_AMOUNT_EDIT (info->distribution_edit),
                                  xaccAccountGetCommoditySCU (account));

    commodity = xaccAccountGetCommodity (account);
    book = gnc_account_get_book (account);
    db = gnc_pricedb_get_db(book);

    prices = gnc_pricedb_lookup_latest_any_currency(db, commodity);
    if (prices)
    {
        /* Use the first existing price */
        if (gnc_commodity_equiv (commodity, gnc_price_get_currency(prices->data)))
            currency = gnc_price_get_commodity(prices->data);
        else
            currency = gnc_price_get_currency(prices->data);
    }
    else
    {
        /* Take a wild guess. */
        currency = gnc_default_currency ();
    }
    gnc_price_list_destroy(prices);

    gnc_currency_edit_set_currency
    (GNC_CURRENCY_EDIT (info->price_currency_edit),
     currency);
}
Exemplo n.º 4
0
static gint
sort_by_value (GtkTreeModel *f_model,
               GtkTreeIter *f_iter_a,
               GtkTreeIter *f_iter_b,
               gpointer user_data)
{
    gnc_commodity *comm_a, *comm_b;
    GNCPrice *price_a, *price_b;
    gboolean result;
    gint value;

    if (!get_prices (f_model, f_iter_a, f_iter_b, &price_a, &price_b))
        return sort_ns_or_cm (f_model, f_iter_a, f_iter_b);

    /*
     * Sorted by commodity because of the tree structure.  Now sort by
     * currency so we're only comparing numbers in the same currency
     * denomination.
     */
    comm_a = gnc_price_get_currency (price_a);
    comm_b = gnc_price_get_currency (price_b);
    if (comm_a && comm_b)
    {
        value = safe_utf8_collate (gnc_commodity_get_namespace (comm_a),
                                   gnc_commodity_get_namespace (comm_b));
        if (value != 0)
            return value;
        value = safe_utf8_collate (gnc_commodity_get_mnemonic (comm_a),
                                   gnc_commodity_get_mnemonic (comm_b));
        if (value != 0)
            return value;
    }

    /*
     * Now do the actual price comparison now we're sure that its an
     * apples to apples comparison.
     */
    result = gnc_numeric_compare (gnc_price_get_value (price_a),
                                  gnc_price_get_value (price_b));
    if (result)
        return result;

    return default_sort (price_a, price_b);
}
static xmlNodePtr
gnc_price_to_dom_tree(const xmlChar *tag, GNCPrice *price)
{
    xmlNodePtr price_xml;
    const gchar *typestr, *sourcestr;
    xmlNodePtr tmpnode;
    gnc_commodity *commodity;
    gnc_commodity *currency;
    Timespec timesp;
    gnc_numeric value;

    if (!(tag && price)) return NULL;

    price_xml = xmlNewNode(NULL, tag);
    if (!price_xml) return NULL;

    commodity = gnc_price_get_commodity(price);
    currency = gnc_price_get_currency(price);

    if (!(commodity && currency)) return NULL;

    tmpnode = guid_to_dom_tree("price:id", gnc_price_get_guid(price));
    if (!add_child_or_kill_parent(price_xml, tmpnode)) return NULL;

    tmpnode = commodity_ref_to_dom_tree("price:commodity", commodity);
    if (!add_child_or_kill_parent(price_xml, tmpnode)) return NULL;

    tmpnode = commodity_ref_to_dom_tree("price:currency", currency);
    if (!add_child_or_kill_parent(price_xml, tmpnode)) return NULL;

    timesp = gnc_price_get_time(price);
    tmpnode = timespec_to_dom_tree("price:time", &timesp);
    if (!add_child_or_kill_parent(price_xml, tmpnode)) return NULL;

    sourcestr = gnc_price_get_source(price);
    if (sourcestr && (strlen(sourcestr) != 0))
    {
        tmpnode = text_to_dom_tree("price:source", sourcestr);
        if (!add_child_or_kill_parent(price_xml, tmpnode)) return NULL;
    }

    typestr = gnc_price_get_typestr(price);
    if (typestr && (strlen(typestr) != 0))
    {
        tmpnode = text_to_dom_tree("price:type", typestr);
        if (!add_child_or_kill_parent(price_xml, tmpnode)) return NULL;
    }

    value = gnc_price_get_value(price);
    tmpnode = gnc_numeric_to_dom_tree("price:value", &value);
    if (!add_child_or_kill_parent(price_xml, tmpnode)) return NULL;

    return price_xml;
}
Exemplo n.º 6
0
/* Get the rate from the price db */
static gnc_numeric
gtu_sr_get_rate_from_db (gnc_commodity *from, gnc_commodity *to)
{
    GNCPrice *prc;
    QofBook *book = gnc_get_current_book ();

    prc = gnc_pricedb_lookup_latest (gnc_pricedb_get_db (book), from, to);

    if (!prc)
        return gnc_numeric_create (100, 100);

    if (gnc_commodity_equiv(from, gnc_price_get_currency(prc)))
        return gnc_numeric_invert(gnc_price_get_value(prc));
    return gnc_price_get_value(prc);
}
Exemplo n.º 7
0
static gboolean
save_price (GncSqlBackend* be, QofInstance* inst)
{
    GNCPrice* pPrice = GNC_PRICE (inst);
    E_DB_OPERATION op;
    gboolean is_infant;
    gboolean is_ok = TRUE;

    g_return_val_if_fail (be != NULL, FALSE);
    g_return_val_if_fail (inst != NULL, FALSE);
    g_return_val_if_fail (GNC_IS_PRICE (inst), FALSE);

    is_infant = qof_instance_get_infant (inst);
    if (qof_instance_get_destroying (inst))
    {
        op = OP_DB_DELETE;
    }
    else if (be->is_pristine_db || is_infant)
    {
        op = OP_DB_INSERT;
    }
    else
    {
        op = OP_DB_UPDATE;
    }

    if (op != OP_DB_DELETE)
    {
        /* Ensure commodity and currency are in the db */
        (void)gnc_sql_save_commodity (be, gnc_price_get_commodity (pPrice));
        is_ok = gnc_sql_save_commodity (be, gnc_price_get_currency (pPrice));
    }

    if (is_ok)
    {
        is_ok = gnc_sql_do_db_operation (be, op, TABLE_NAME, GNC_ID_PRICE, pPrice,
                                         col_table);
    }

    return is_ok;
}