Ejemplo n.º 1
0
static gboolean
check_time (Timespec ts, gboolean always_print)
{
    Timespec ts_2;
    char str[128];
    gboolean ok;

    ts.tv_nsec = MIN (ts.tv_nsec, 999999999);
    ts.tv_nsec /= 1000;
    ts.tv_nsec *= 1000;

    gnc_timespec_to_iso8601_buff (ts, str);

    /* The time, in seconds, everywhere on the planet, is always
     * the same, and is independent of location.  In particular,
     * the time, in seconds, is identical to the local time in
     * Greenwich (GMT).
     */
    ts_2 = gnc_iso8601_to_timespec_gmt (str);

    ok = timespec_equal (&ts, &ts_2);

    if (!ok || always_print)
    {
        fprintf (stderr,
                 "\n%" G_GINT64_FORMAT ":%ld -> %s ->\n"
                 "\t%" G_GINT64_FORMAT ":%ld"
                 " (diff of %" G_GINT64_FORMAT " secs %ld nsecs)\n",
                 ts.tv_sec, ts.tv_nsec, str,
                 ts_2.tv_sec, ts_2.tv_nsec,
                 ts.tv_sec - ts_2.tv_sec, ts.tv_nsec - ts_2.tv_nsec);

        if (!ok)
        {
            failure ("timespec to iso8601 string conversion failed");
            return FALSE;
        }
    }

    success ("timespec to iso8601 string conversion passes");

    return TRUE;
}
Ejemplo n.º 2
0
gchar*
kvp_value_to_string(const KvpValue *val)
{
    gchar *tmp1;
    gchar *tmp2;
    const gchar *ctmp;

    g_return_val_if_fail(val, NULL);

    switch (kvp_value_get_type(val))
    {
    case KVP_TYPE_GINT64:
        return g_strdup_printf("KVP_VALUE_GINT64(%" G_GINT64_FORMAT ")",
                               kvp_value_get_gint64(val));
        break;

    case KVP_TYPE_DOUBLE:
        return g_strdup_printf("KVP_VALUE_DOUBLE(%g)",
                               kvp_value_get_double(val));
        break;

    case KVP_TYPE_NUMERIC:
        tmp1 = gnc_numeric_to_string(kvp_value_get_numeric(val));
        tmp2 = g_strdup_printf("KVP_VALUE_NUMERIC(%s)", tmp1 ? tmp1 : "");
        g_free(tmp1);
        return tmp2;
        break;

    case KVP_TYPE_STRING:
        tmp1 = kvp_value_get_string (val);
        return g_strdup_printf("KVP_VALUE_STRING(%s)", tmp1 ? tmp1 : "");
        break;

    case KVP_TYPE_GUID:
        gchar guidstr[GUID_ENCODING_LENGTH+1];
        guid_to_string_buff(kvp_value_get_guid(val),guidstr);
        tmp2 = g_strdup_printf("KVP_VALUE_GUID(%s)", guidstr);
        return tmp2;
        break;

    case KVP_TYPE_TIMESPEC:
        tmp1 = g_new0 (char, 40);
        gnc_timespec_to_iso8601_buff (kvp_value_get_timespec (val), tmp1);
        tmp2 = g_strdup_printf("KVP_VALUE_TIMESPEC(%s)", tmp1);
        g_free(tmp1);
        return tmp2;
        break;

    case KVP_TYPE_BINARY:
    {
        guint64 len;
        void *data;
        data = kvp_value_get_binary(val, &len);
        tmp1 = binary_to_string(data, len);
        return g_strdup_printf("KVP_VALUE_BINARY(%s)", tmp1 ? tmp1 : "");
    }
    break;

    case KVP_TYPE_GLIST:
        tmp1 = kvp_value_glist_to_string(kvp_value_get_glist(val));
        tmp2 = g_strdup_printf("KVP_VALUE_GLIST(%s)", tmp1 ? tmp1 : "");
        g_free(tmp1);
        return tmp2;
        break;

    case KVP_TYPE_FRAME:
        tmp1 = kvp_frame_to_string(kvp_value_get_frame(val));
        tmp2 = g_strdup_printf("KVP_VALUE_FRAME(%s)", tmp1 ? tmp1 : "");
        g_free(tmp1);
        return tmp2;
        break;

    case KVP_TYPE_GDATE:
        return g_strdup_printf("KVP_VALUE_GDATE(%04d-%02d-%02d)",
                               g_date_get_year(&val->value.gdate),
                               g_date_get_month(&val->value.gdate),
                               g_date_get_day(&val->value.gdate));
    default:
	break;
    }
    g_assert(FALSE); /* must not be reached */
    return g_strdup("");
}
Ejemplo n.º 3
0
char *
gnc_time64_to_iso8601_buff (time64 time, char * buff)
{
    Timespec ts = {time, 0};
    return gnc_timespec_to_iso8601_buff (ts, buff);
}
Ejemplo n.º 4
0
void
xaccTransWriteLog (Transaction *trans, char flag)
{
    GList *node;
    char trans_guid_str[GUID_ENCODING_LENGTH + 1];
    char split_guid_str[GUID_ENCODING_LENGTH + 1];
    const char *trans_notes;
    char dnow[100], dent[100], dpost[100], drecn[100];
    Timespec ts;

    if (!gen_logs) return;
    if (!trans_log) return;

    timespecFromTime_t(&ts, time(NULL));
    gnc_timespec_to_iso8601_buff (ts, dnow);

    timespecFromTime_t(&ts, trans->date_entered.tv_sec);
    gnc_timespec_to_iso8601_buff (ts, dent);

    timespecFromTime_t(&ts, trans->date_posted.tv_sec);
    gnc_timespec_to_iso8601_buff (ts, dpost);

    guid_to_string_buff (xaccTransGetGUID(trans), trans_guid_str);
    trans_notes = xaccTransGetNotes(trans);
    fprintf (trans_log, "===== START\n");

    for (node = trans->splits; node; node = node->next)
    {
        Split *split = node->data;
        const char * accname = "";
        char acc_guid_str[GUID_ENCODING_LENGTH + 1];
        gnc_numeric amt, val;

        if (xaccSplitGetAccount(split))
        {
            accname = xaccAccountGetName (xaccSplitGetAccount(split));
            guid_to_string_buff(xaccAccountGetGUID(xaccSplitGetAccount(split)),
                                acc_guid_str);
        }
        else
        {
            acc_guid_str[0] = '\0';
        }

        timespecFromTime_t(&ts, split->date_reconciled.tv_sec);
        gnc_timespec_to_iso8601_buff (ts, drecn);

        guid_to_string_buff (xaccSplitGetGUID(split), split_guid_str);
        amt = xaccSplitGetAmount (split);
        val = xaccSplitGetValue (split);

        /* use tab-separated fields */
        fprintf (trans_log,
                 "%c\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s\t"
                 "%s\t%s\t%s\t%s\t%c\t%" G_GINT64_FORMAT "/%" G_GINT64_FORMAT "\t%" G_GINT64_FORMAT "/%" G_GINT64_FORMAT "\t%s\n",
                 flag,
                 trans_guid_str, split_guid_str,  /* trans+split make up unique id */
                 /* Note that the next three strings always exist,
                 		* so we don't need to test them. */
                 dnow,
                 dent,
                 dpost,
                 acc_guid_str,
                 accname ? accname : "",
                 trans->num ? trans->num : "",
                 trans->description ? trans->description : "",
                 trans_notes ? trans_notes : "",
                 split->memo ? split->memo : "",
                 split->action ? split->action : "",
                 split->reconciled,
                 gnc_numeric_num(amt),
                 gnc_numeric_denom(amt),
                 gnc_numeric_num(val),
                 gnc_numeric_denom(val),
                 /* The next string always exists. No need to test it. */
                 drecn);
    }

    fprintf (trans_log, "===== END\n");

    /* get data out to the disk */
    fflush (trans_log);
}
Ejemplo n.º 5
0
static void dump_split_record(split_record record)
{
    char * string_ptr = NULL;
    char string_buf[256];

    DEBUG("dump_split_record(): Start...");
    if (record.log_action_present)
    {
        switch (record.log_action)
        {
        case split_record::LOG_BEGIN_EDIT:
            DEBUG("Log action: LOG_BEGIN_EDIT");
            break;
        case split_record::LOG_DELETE:
            DEBUG("Log action: LOG_DELETE");
            break;
        case split_record::LOG_COMMIT:
            DEBUG("Log action: LOG_COMMIT");
            break;
        case split_record::LOG_ROLLBACK:
            DEBUG("Log action: LOG_ROLLBACK");
            break;
        }
    }
    if (record.trans_guid_present)
    {
        DEBUG("Transaction GncGUID: %s", guid_to_string (&(record.trans_guid)));
    }
    if (record.split_guid_present)
    {
        DEBUG("Split GncGUID: %s", guid_to_string (&(record.split_guid)));
    }
    if (record.log_date_present)
    {
        gnc_timespec_to_iso8601_buff (record.log_date, string_buf);
        DEBUG("Log entry date: %s", string_buf);
    }
    if (record.date_entered_present)
    {
        gnc_timespec_to_iso8601_buff (record.date_entered, string_buf);
        DEBUG("Date entered: %s", string_buf);
    }
    if (record.date_posted_present)
    {
        gnc_timespec_to_iso8601_buff (record.date_posted, string_buf);
        DEBUG("Date posted: %s", string_buf);
    }
    if (record.acc_guid_present)
    {
        DEBUG("Account GncGUID: %s", guid_to_string (&(record.acc_guid)));
    }
    if (record.acc_name_present)
    {
        DEBUG("Account name: %s", record.acc_name);
    }
    if (record.trans_num_present)
    {
        DEBUG("Transaction number: %s", record.trans_num);
    }
    if (record.trans_descr_present)
    {
        DEBUG("Transaction description: %s", record.trans_descr);
    }
    if (record.trans_notes_present)
    {
        DEBUG("Transaction notes: %s", record.trans_notes);
    }
    if (record.split_memo_present)
    {
        DEBUG("Split memo: %s", record.split_memo);
    }
    if (record.split_action_present)
    {
        DEBUG("Split action: %s", record.split_action);
    }
    if (record.split_reconcile_present)
    {
        DEBUG("Split reconcile: %c", record.split_reconcile);
    }
    if (record.amount_present)
    {
        string_ptr = gnc_numeric_to_string(record.amount);
        DEBUG("Record amount: %s", string_ptr);
        g_free(string_ptr);
    }
    if (record.value_present)
    {
        string_ptr = gnc_numeric_to_string(record.value);
        DEBUG("Record value: %s", string_ptr);
        g_free(string_ptr);
    }
    if (record.date_reconciled_present)
    {
        gnc_timespec_to_iso8601_buff (record.date_reconciled, string_buf);
        DEBUG("Reconciled date: %s", string_buf);
    }
}
Ejemplo n.º 6
0
int ofx_proc_transaction_cb(struct OfxTransactionData data, void * transaction_user_data)
{
    char dest_string[255];
    time64 current_time = gnc_time (NULL);
    Account *account;
    Account *investment_account = NULL;
    Account *income_account = NULL;
    gchar *investment_account_text, *investment_account_onlineid;
    gnc_commodity *currency = NULL;
    gnc_commodity *investment_commodity = NULL;
    gnc_numeric gnc_amount, gnc_units;
    QofBook *book;
    Transaction *transaction;
    Split *split;
    gchar *notes, *tmp;

    g_assert(gnc_ofx_importer_gui);

    if (!data.account_id_valid)
    {
        PERR("account ID for this transaction is unavailable!");
        return 0;
    }

    account = gnc_import_select_account(gnc_gen_trans_list_widget(gnc_ofx_importer_gui),
                                        data.account_id, 0, NULL, NULL,
                                        ACCT_TYPE_NONE, NULL, NULL);
    if (account == NULL)
    {
        PERR("Unable to find account for id %s", data.account_id);
        return 0;
    }
    /***** Validate the input strings to ensure utf8 *****/
    if (data.name_valid)
        gnc_utf8_strip_invalid(data.name);
    if (data.memo_valid)
        gnc_utf8_strip_invalid(data.memo);
    if (data.check_number_valid)
        gnc_utf8_strip_invalid(data.check_number);
    if (data.reference_number_valid)
        gnc_utf8_strip_invalid(data.reference_number);

    /***** Create the transaction and setup transaction data *******/
    book = gnc_account_get_book(account);
    transaction = xaccMallocTransaction(book);
    xaccTransBeginEdit(transaction);

    /* Note: Unfortunately libofx <= 0.9.5 will not report a missing
     * date field as an invalid one. Instead, it will report it as
     * valid and return a completely bogus date. Starting with
     * libofx-0.9.6 (not yet released as of 2012-09-09), it will still
     * be reported as valid but at least the date integer itself is
     * just plain zero. */
    if (data.date_posted_valid && (data.date_posted != 0))
    {
        /* The hopeful case: We have a posted_date */
        xaccTransSetDatePostedSecsNormalized(transaction, data.date_posted);
    } else if (data.date_initiated_valid && (data.date_initiated != 0))
    {
        /* No posted date? Maybe we have an initiated_date */
        xaccTransSetDatePostedSecsNormalized(transaction, data.date_initiated);
    }
    else
    {
        /* Uh no, no valid date. As a workaround use today's date */
        xaccTransSetDatePostedSecsNormalized(transaction, current_time);
    }

    xaccTransSetDateEnteredSecs(transaction, current_time);

    /* Put transaction name in Description, or memo if name unavailable */
    if (data.name_valid)
    {
        xaccTransSetDescription(transaction, data.name);
    }
    else if (data.memo_valid)
    {
        xaccTransSetDescription(transaction, data.memo);
    }

    /* Put everything else in the Notes field */
    notes = g_strdup_printf("OFX ext. info: ");

    if (data.transactiontype_valid)
    {
        tmp = notes;
        notes = g_strdup_printf("%s%s%s", tmp, "|Trans type:",
                                gnc_ofx_ttype_to_string(data.transactiontype));
        g_free(tmp);
    }

    if (data.invtransactiontype_valid)
    {
        tmp = notes;
        notes = g_strdup_printf("%s%s%s", tmp, "|Investment Trans type:",
                                gnc_ofx_invttype_to_str(data.invtransactiontype));
        g_free(tmp);
    }
    if (data.memo_valid && data.name_valid) /* Copy only if memo wasn't put in Description */
    {
        tmp = notes;
        notes = g_strdup_printf("%s%s%s", tmp, "|Memo:", data.memo);
        g_free(tmp);
    }
    if (data.date_funds_available_valid)
    {
        Timespec ts;
        timespecFromTime64(&ts, data.date_funds_available);
        gnc_timespec_to_iso8601_buff (ts, dest_string);
        tmp = notes;
        notes = g_strdup_printf("%s%s%s", tmp, "|Date funds available:", dest_string);
        g_free(tmp);
    }
    if (data.server_transaction_id_valid)
    {
        tmp = notes;
        notes = g_strdup_printf("%s%s%s", tmp, "|Server trans ID (conf. number):", data.server_transaction_id);
        g_free(tmp);
    }
    if (data.standard_industrial_code_valid)
    {
        tmp = notes;
        notes = g_strdup_printf("%s%s%ld", tmp, "|Standard Industrial Code:", data.standard_industrial_code);
        g_free(tmp);

    }
    if (data.payee_id_valid)
    {
        tmp = notes;
        notes = g_strdup_printf("%s%s%s", tmp, "|Payee ID:", data.payee_id);
        g_free(tmp);
    }

    //PERR("WRITEME: GnuCash ofx_proc_transaction():Add PAYEE and ADRESS here once supported by libofx! Notes=%s\n", notes);

    /* Ideally, gnucash should process the corrected transactions */
    if (data.fi_id_corrected_valid)
    {
        PERR("WRITEME: GnuCash ofx_proc_transaction(): WARNING: This transaction corrected a previous transaction, but we created a new one instead!\n");
        tmp = notes;
        notes = g_strdup_printf("%s%s%s%s", tmp, "|This corrects transaction #", data.fi_id_corrected, "but GnuCash didn't process the correction!");
        g_free(tmp);
    }
    xaccTransSetNotes(transaction, notes);
    g_free(notes);

    if (data.account_ptr && data.account_ptr->currency_valid)
    {
        DEBUG("Currency from libofx: %s", data.account_ptr->currency);
        currency = gnc_commodity_table_lookup( gnc_get_current_commodities (),
                                               GNC_COMMODITY_NS_CURRENCY,
                                               data.account_ptr->currency);
    }
    else
    {
        DEBUG("Currency from libofx unavailable, defaulting to account's default");
        currency = xaccAccountGetCommodity(account);
    }

    xaccTransSetCurrency(transaction, currency);
    if (data.amount_valid)
    {
        if (!data.invtransactiontype_valid)
        {
            /***** Process a normal transaction ******/
            DEBUG("Adding split; Ordinary banking transaction, money flows from or into the source account");
            split = xaccMallocSplit(book);
            xaccTransAppendSplit(transaction, split);
            xaccAccountInsertSplit(account, split);

            gnc_amount = gnc_ofx_numeric_from_double_txn(data.amount, transaction);
            xaccSplitSetBaseValue(split, gnc_amount, xaccTransGetCurrency(transaction));

            /* set tran-num and/or split-action per book option */
            if (data.check_number_valid)
            {
                gnc_set_num_action(transaction, split, data.check_number, NULL);
            }
            else if (data.reference_number_valid)
            {
                gnc_set_num_action(transaction, split, data.reference_number, NULL);
            }
            /* Also put the ofx transaction's memo in the
             * split's memo field */
            if (data.memo_valid)
            {
                xaccSplitSetMemo(split, data.memo);
            }
            if (data.fi_id_valid)
            {
                gnc_import_set_split_online_id(split, data.fi_id);
            }
        }

        else if (data.unique_id_valid
                 && data.security_data_valid
                 && data.security_data_ptr != NULL
                 && data.security_data_ptr->secname_valid)
        {
            gboolean choosing_account = TRUE;
            /********* Process an investment transaction **********/
            /* Note that the ACCT_TYPE_STOCK account type
               should be replaced with something derived from
               data.invtranstype*/

            // We have an investment transaction. First select the correct commodity.
            investment_commodity = gnc_import_select_commodity(data.unique_id,
                                   FALSE,
                                   NULL,
                                   NULL);
            if (investment_commodity != NULL)
            {
                // As we now have the commodity, select the account with that commodity.

                investment_account_text = g_strdup_printf( /* This string is a default account
                                                              name. It MUST NOT contain the
                                                              character ':' anywhere in it or
                                                              in any translations.  */
                                              _("Stock account for security \"%s\""),
                                              data.security_data_ptr->secname);

                investment_account_onlineid = g_strdup_printf( "%s%s", data.account_id, data.unique_id);
                investment_account = gnc_import_select_account(NULL,
                                                               investment_account_onlineid,
                                                               1,
                                                               investment_account_text,
                                                               investment_commodity,
                                                               ACCT_TYPE_STOCK,
                                                               NULL,
                                                               NULL);

                // but use it only if that's really the right commodity
                if (investment_account
                        && xaccAccountGetCommodity(investment_account) != investment_commodity)
                    investment_account = NULL;

                // Loop until we either have an account, or the user pressed Cancel
                while (!investment_account && choosing_account)
                {
                    // No account with correct commodity automatically found.

                    // But are we in auto-create mode and already know a parent?
                    if (auto_create_commodity && ofx_parent_account)
                    {
                        // Yes, so use that as parent when auto-creating the new account below.
                        investment_account = ofx_parent_account;
                    }
                    else
                    {
                        // Let the user choose an account
                        investment_account = gnc_import_select_account(
                                                 gnc_gen_trans_list_widget(gnc_ofx_importer_gui),
                                                 data.unique_id,
                                                 TRUE,
                                                 investment_account_text,
                                                 investment_commodity,
                                                 ACCT_TYPE_STOCK,
                                                 NULL,
                                                 &choosing_account);
                    }
                    // Does the chosen account have the right commodity?
                    if (investment_account && xaccAccountGetCommodity(investment_account) != investment_commodity)
                    {
                        if (auto_create_commodity
                                && xaccAccountTypesCompatible(xaccAccountGetType(investment_account),
                                                              ACCT_TYPE_STOCK))
                        {
                            // The user chose an account, but it does
                            // not have the right commodity. Also,
                            // auto-creation is on. Hence, we create a
                            // new child account of the selected one,
                            // and this one will have the right
                            // commodity.
                            Account *parent_account = investment_account;
                            investment_account =
                                gnc_ofx_new_account(investment_account_text,
                                                    investment_commodity,
                                                    parent_account,
                                                    ACCT_TYPE_STOCK);
                            if (investment_account)
                            {
                                gnc_import_set_acc_online_id(investment_account, data.unique_id);
                                choosing_account = FALSE;
                                ofx_parent_account = parent_account;
                            }
                            else
                            {
                                ofx_parent_account = NULL;
                            }
                        }
                        else
                        {
                            // No account with matching commodity. Ask the user
                            // whether to continue or abort.
                            choosing_account =
                                gnc_verify_dialog(
                                    gnc_gen_trans_list_widget(gnc_ofx_importer_gui), TRUE,
                                    "The chosen account \"%s\" does not have the correct "
                                    "currency/security \"%s\" (it has \"%s\" instead). "
                                    "This account cannot be used. "
                                    "Do you want to choose again?",
                                    xaccAccountGetName(investment_account),
                                    gnc_commodity_get_fullname(investment_commodity),
                                    gnc_commodity_get_fullname(xaccAccountGetCommodity(investment_account)));
                            // We must also delete the online_id that was set in gnc_import_select_account()
                            gnc_import_set_acc_online_id(investment_account, "");
                            investment_account = NULL;
                        }
                    }
                }
                if (!investment_account)
                {
                    PERR("No investment account found for text: %s\n", investment_account_text);
                }
                g_free (investment_account_text);
                g_free (investment_account_onlineid);
                investment_account_text = NULL;

                if (investment_account != NULL &&
                        data.unitprice_valid &&
                        data.units_valid &&
                        ( data.invtransactiontype != OFX_INCOME ) )
                {
                    DEBUG("Adding investment split; Money flows from or into the stock account");
                    split = xaccMallocSplit(book);
                    xaccTransAppendSplit(transaction, split);
                    xaccAccountInsertSplit(investment_account, split);

                    gnc_amount = gnc_ofx_numeric_from_double (ofx_get_investment_amount(&data),
                                 investment_commodity);
                    gnc_units = gnc_ofx_numeric_from_double (data.units, investment_commodity);
                    xaccSplitSetAmount(split, gnc_units);
                    xaccSplitSetValue(split, gnc_amount);

                    /* set tran-num and/or split-action per book option */
                    if (data.check_number_valid)
                    {
                        gnc_set_num_action(transaction, split, data.check_number, NULL);
                    }
                    else if (data.reference_number_valid)
                    {
                        gnc_set_num_action(transaction, split,
                                                data.reference_number, NULL);
                    }
                    if (data.security_data_ptr->memo_valid)
                    {
                        xaccSplitSetMemo(split, data.security_data_ptr->memo);
                    }
                    if (data.fi_id_valid)
                    {
                        gnc_import_set_split_online_id(split, data.fi_id);
                    }
                }
                else
                {
                    if (investment_account)
                        PERR("The investment account, units or unitprice was not found for the investment transaction");
                }
            }
            else
            {
                PERR("Commodity not found for the investment transaction");
            }

            if (data.invtransactiontype_valid && investment_account)
            {
                if (data.invtransactiontype == OFX_REINVEST
                        || data.invtransactiontype == OFX_INCOME)
                {
                    DEBUG("Now let's find an account for the destination split");

                    income_account = gnc_ofx_kvp_get_assoc_account(investment_account);

                    if (income_account == NULL)
                    {
                        DEBUG("Couldn't find an associated income account");
                        investment_account_text = g_strdup_printf( /* This string is a default account
                                                                      name. It MUST NOT contain the
                                                                      character ':' anywhere in it or
                                                                      in any translations.  */
                                                      _("Income account for security \"%s\""),
                                                      data.security_data_ptr->secname);
                        income_account = gnc_import_select_account(
                                             gnc_gen_trans_list_widget(gnc_ofx_importer_gui),
                                             NULL,
                                             1,
                                             investment_account_text,
                                             currency,
                                             ACCT_TYPE_INCOME,
                                             NULL,
                                             NULL);
                        gnc_ofx_kvp_set_assoc_account(investment_account,
                                                      income_account);
                        DEBUG("KVP written");

                    }
                    else
                    {
                        DEBUG("Found at least one associated income account");
                    }
                }
                if (income_account != NULL &&
                        data.invtransactiontype == OFX_REINVEST)
                {
                    DEBUG("Adding investment split; Money flows from the income account");
                    split = xaccMallocSplit(book);
                    xaccTransAppendSplit(transaction, split);
                    xaccAccountInsertSplit(income_account, split);

                    gnc_amount = gnc_ofx_numeric_from_double_txn (data.amount, transaction);
                    xaccSplitSetBaseValue(split, gnc_amount, xaccTransGetCurrency(transaction));

                    // Set split memo from ofx transaction name or memo
                    gnc_ofx_set_split_memo(&data, split);
                }
                if (income_account != NULL &&
                        data.invtransactiontype == OFX_INCOME)
                {
                    DEBUG("Adding investment split; Money flows from the income account");
                    split = xaccMallocSplit(book);
                    xaccTransAppendSplit(transaction, split);
                    xaccAccountInsertSplit(income_account, split);

                    gnc_amount = gnc_ofx_numeric_from_double_txn (-data.amount,/*OFX_INCOME amounts come in as positive numbers*/
                                 transaction);
                    xaccSplitSetBaseValue(split, gnc_amount, xaccTransGetCurrency(transaction));

                    // Set split memo from ofx transaction name or memo
                    gnc_ofx_set_split_memo(&data, split);
                }
            }

            if (data.invtransactiontype_valid
                    && data.invtransactiontype != OFX_REINVEST)
            {
                DEBUG("Adding investment split; Money flows from or to the cash account");
                split = xaccMallocSplit(book);
                xaccTransAppendSplit(transaction, split);
                xaccAccountInsertSplit(account, split);

                gnc_amount = gnc_ofx_numeric_from_double_txn(
                                 -ofx_get_investment_amount(&data), transaction);
                xaccSplitSetBaseValue(split, gnc_amount,
                                      xaccTransGetCurrency(transaction));

                // Set split memo from ofx transaction name or memo
                gnc_ofx_set_split_memo(&data, split);
            }
        }

        /* Send transaction to importer GUI. */
        if (xaccTransCountSplits(transaction) > 0)
        {
            DEBUG("%d splits sent to the importer gui", xaccTransCountSplits(transaction));
            gnc_gen_trans_list_add_trans (gnc_ofx_importer_gui, transaction);
        }
        else
        {
            PERR("No splits in transaction (missing account?), ignoring.");
            xaccTransDestroy(transaction);
            xaccTransCommitEdit(transaction);
        }
    }
    else
    {
        PERR("The transaction doesn't have a valid amount");
        xaccTransDestroy(transaction);
        xaccTransCommitEdit(transaction);
    }

    return 0;
}//end ofx_proc_transaction()