r20409 - gnucash/trunk/src/import-export/ofx - Code cleanup in ofx importer; refactoring to get away from the single giant long function.

Christian Stimming cstim at code.gnucash.org
Sat Mar 12 19:03:05 EST 2011


Author: cstim
Date: 2011-03-12 19:03:04 -0500 (Sat, 12 Mar 2011)
New Revision: 20409
Trac: http://svn.gnucash.org/trac/changeset/20409

Modified:
   gnucash/trunk/src/import-export/ofx/gnc-ofx-import.c
Log:
Code cleanup in ofx importer; refactoring to get away from the single giant long function.

Modified: gnucash/trunk/src/import-export/ofx/gnc-ofx-import.c
===================================================================
--- gnucash/trunk/src/import-export/ofx/gnc-ofx-import.c	2011-03-13 00:02:53 UTC (rev 20408)
+++ gnucash/trunk/src/import-export/ofx/gnc-ofx-import.c	2011-03-13 00:03:04 UTC (rev 20409)
@@ -77,21 +77,113 @@
 int ofx_proc_account_cb(struct OfxAccountData data, void * account_user_data);
 double ofx_get_investment_amount(struct OfxTransactionData data);
 
+static const gchar *gnc_ofx_ttype_to_string(TransactionType t)
+{
+    switch (t)
+    {
+    case OFX_CREDIT:
+        return "Generic credit";
+    case OFX_DEBIT:
+        return "Generic debit";
+    case OFX_INT:
+        return "Interest earned or paid (Note: Depends on signage of amount)";
+    case OFX_DIV:
+        return "Dividend";
+    case OFX_FEE:
+        return "FI fee";
+    case OFX_SRVCHG:
+        return "Service charge";
+    case OFX_DEP:
+        return "Deposit";
+    case OFX_ATM:
+        return "ATM debit or credit (Note: Depends on signage of amount)";
+    case OFX_POS:
+        return "Point of sale debit or credit (Note: Depends on signage of amount)";
+    case OFX_XFER:
+        return "Transfer";
+    case OFX_CHECK:
+        return "Check";
+    case OFX_PAYMENT:
+        return "Electronic payment";
+    case OFX_CASH:
+        return "Cash withdrawal";
+    case OFX_DIRECTDEP:
+        return "Direct deposit";
+    case OFX_DIRECTDEBIT:
+        return "Merchant initiated debit";
+    case OFX_REPEATPMT:
+        return "Repeating payment/standing order";
+    case OFX_OTHER:
+        return "Other";
+    default:
+        return "Unknown transaction type";
+    }
+}
+
+static const gchar *gnc_ofx_invttype_to_str(InvTransactionType t)
+{
+    switch (t)
+    {
+    case OFX_BUYDEBT:
+        return "BUYDEBT (Buy debt security)";
+    case OFX_BUYMF:
+        return "BUYMF (Buy mutual fund)";
+    case OFX_BUYOPT:
+        return "BUYOPT (Buy option)";
+    case OFX_BUYOTHER:
+        return "BUYOTHER (Buy other security type)";
+    case OFX_BUYSTOCK:
+        return "BUYSTOCK (Buy stock))";
+    case OFX_CLOSUREOPT:
+        return "CLOSUREOPT (Close a position for an option)";
+    case OFX_INCOME:
+        return "INCOME (Investment income is realized as cash into the investment account)";
+    case OFX_INVEXPENSE:
+        return "INVEXPENSE (Misc investment expense that is associated with a specific security)";
+    case OFX_JRNLFUND:
+        return "JRNLFUND (Journaling cash holdings between subaccounts within the same investment account)";
+    case OFX_MARGININTEREST:
+        return "MARGININTEREST (Margin interest expense)";
+    case OFX_REINVEST:
+        return "REINVEST (Reinvestment of income)";
+    case OFX_RETOFCAP:
+        return "RETOFCAP (Return of capital)";
+    case OFX_SELLDEBT:
+        return "SELLDEBT (Sell debt security.  Used when debt is sold, called, or reached maturity)";
+    case OFX_SELLMF:
+        return "SELLMF (Sell mutual fund)";
+    case OFX_SELLOPT:
+        return "SELLOPT (Sell option)";
+    case OFX_SELLOTHER:
+        return "SELLOTHER (Sell other type of security)";
+    case OFX_SELLSTOCK:
+        return "SELLSTOCK (Sell stock)";
+    case OFX_SPLIT:
+        return "SPLIT (Stock or mutial fund split)";
+    case OFX_TRANSFER:
+        return "TRANSFER (Transfer holdings in and out of the investment account)";
+    default:
+        return "ERROR, this investment transaction type is unknown.  This is a bug in ofxdump";
+    }
+
+}
+
+
 int ofx_proc_security_cb(const struct OfxSecurityData data, void * security_user_data)
 {
     const char* cusip = NULL;
     const char* default_fullname = NULL;
     const char* default_mnemonic = NULL;
 
-    if (data.unique_id_valid == true)
+    if (data.unique_id_valid)
     {
         cusip = data.unique_id;
     }
-    if (data.secname_valid == true)
+    if (data.secname_valid)
     {
         default_fullname = data.secname;
     }
-    if (data.ticker_valid == true)
+    if (data.ticker_valid)
     {
         default_mnemonic = data.ticker;
     }
@@ -150,6 +242,33 @@
     return 0;
 }
 
+static void gnc_ofx_set_split_memo(const struct OfxTransactionData* data, Split *split)
+{
+    g_assert(data);
+    g_assert(split);
+    /* Also put the ofx transaction name in
+     * the splits memo field, or ofx memo if
+     * name is unavailable */
+    if (data->name_valid)
+    {
+        xaccSplitSetMemo(split, data->name);
+    }
+    else if (data->memo_valid)
+    {
+        xaccSplitSetMemo(split, data->memo);
+    }
+}
+static gnc_numeric gnc_ofx_numeric_from_double(double value, const gnc_commodity *commodity)
+{
+    return double_to_gnc_numeric (value,
+                                  gnc_commodity_get_fraction(commodity),
+                                  GNC_HOW_RND_ROUND_HALF_UP);
+}
+static gnc_numeric gnc_ofx_numeric_from_double_txn(double value, const Transaction* txn)
+{
+    return gnc_ofx_numeric_from_double(value, xaccTransGetCurrency(txn));
+}
+
 int ofx_proc_transaction_cb(struct OfxTransactionData data, void * transaction_user_data)
 {
     char dest_string[255];
@@ -171,502 +290,356 @@
 
     g_assert(gnc_ofx_importer_gui);
 
-    if (data.account_id_valid == true)
+    if (!data.account_id_valid)
     {
-        account = gnc_import_select_account(NULL, data.account_id, 0, NULL, NULL,
-                                            ACCT_TYPE_NONE, NULL, NULL);
-        if (account != NULL)
-        {
-            /***** 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);
+        PERR("account ID for this transaction is unavailable!");
+        return 0;
+    }
 
-            /***** Create the transaction and setup transaction data *******/
-            book = gnc_account_get_book(account);
-            transaction = xaccMallocTransaction(book);
-            xaccTransBeginEdit(transaction);
+    account = gnc_import_select_account(NULL, 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);
 
-            if (data.date_initiated_valid == true)
-            {
-                xaccTransSetDatePostedSecs(transaction, data.date_initiated);
-            }
-            else if (data.date_posted_valid == true)
-            {
-                xaccTransSetDatePostedSecs(transaction, data.date_posted);
-            }
+    /***** Create the transaction and setup transaction data *******/
+    book = gnc_account_get_book(account);
+    transaction = xaccMallocTransaction(book);
+    xaccTransBeginEdit(transaction);
 
-            if (data.date_posted_valid == true)
-            {
-                xaccTransSetDatePostedSecs(transaction, data.date_posted);
-            }
+    if (data.date_initiated_valid)
+    {
+        xaccTransSetDatePostedSecs(transaction, data.date_initiated);
+    }
+    else if (data.date_posted_valid)
+    {
+        xaccTransSetDatePostedSecs(transaction, data.date_posted);
+    }
 
-            current_time = time(NULL);
-            xaccTransSetDateEnteredSecs(transaction, mktime(localtime(&current_time)));
+    if (data.date_posted_valid)
+    {
+        xaccTransSetDatePostedSecs(transaction, data.date_posted);
+    }
 
-            if (data.check_number_valid == true)
-            {
-                xaccTransSetNum(transaction, data.check_number);
-            }
-            else if (data.reference_number_valid == true)
-            {
-                xaccTransSetNum(transaction, data.reference_number);
-            }
-            /* Put transaction name in Description, or memo if name unavailable */
-            if (data.name_valid == true)
-            {
-                xaccTransSetDescription(transaction, data.name);
-            }
-            else if (data.memo_valid == true)
-            {
-                xaccTransSetDescription(transaction, data.memo);
-            }
+    current_time = time(NULL);
+    xaccTransSetDateEnteredSecs(transaction, mktime(localtime(&current_time)));
 
-            /* Put everything else in the Notes field */
-            notes = g_strdup_printf("OFX ext. info: ");
+    if (data.check_number_valid)
+    {
+        xaccTransSetNum(transaction, data.check_number);
+    }
+    else if (data.reference_number_valid)
+    {
+        xaccTransSetNum(transaction, data.reference_number);
+    }
+    /* 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);
+    }
 
-            if (data.transactiontype_valid == true)
-            {
-                switch (data.transactiontype)
-                {
-                case OFX_CREDIT:
-                    strncpy(dest_string, "Generic credit", sizeof(dest_string));
-                    break;
-                case OFX_DEBIT:
-                    strncpy(dest_string, "Generic debit", sizeof(dest_string));
-                    break;
-                case OFX_INT:
-                    strncpy(dest_string, "Interest earned or paid (Note: Depends on signage of amount)", sizeof(dest_string));
-                    break;
-                case OFX_DIV:
-                    strncpy(dest_string, "Dividend", sizeof(dest_string));
-                    break;
-                case OFX_FEE:
-                    strncpy(dest_string, "FI fee", sizeof(dest_string));
-                    break;
-                case OFX_SRVCHG:
-                    strncpy(dest_string, "Service charge", sizeof(dest_string));
-                    break;
-                case OFX_DEP:
-                    strncpy(dest_string, "Deposit", sizeof(dest_string));
-                    break;
-                case OFX_ATM:
-                    strncpy(dest_string, "ATM debit or credit (Note: Depends on signage of amount)", sizeof(dest_string));
-                    break;
-                case OFX_POS:
-                    strncpy(dest_string, "Point of sale debit or credit (Note: Depends on signage of amount)", sizeof(dest_string));
-                    break;
-                case OFX_XFER:
-                    strncpy(dest_string, "Transfer", sizeof(dest_string));
-                    break;
-                case OFX_CHECK:
-                    strncpy(dest_string, "Check", sizeof(dest_string));
-                    break;
-                case OFX_PAYMENT:
-                    strncpy(dest_string, "Electronic payment", sizeof(dest_string));
-                    break;
-                case OFX_CASH:
-                    strncpy(dest_string, "Cash withdrawal", sizeof(dest_string));
-                    break;
-                case OFX_DIRECTDEP:
-                    strncpy(dest_string, "Direct deposit", sizeof(dest_string));
-                    break;
-                case OFX_DIRECTDEBIT:
-                    strncpy(dest_string, "Merchant initiated debit", sizeof(dest_string));
-                    break;
-                case OFX_REPEATPMT:
-                    strncpy(dest_string, "Repeating payment/standing order", sizeof(dest_string));
-                    break;
-                case OFX_OTHER:
-                    strncpy(dest_string, "Other", sizeof(dest_string));
-                    break;
-                default :
-                    strncpy(dest_string, "Unknown transaction type", sizeof(dest_string));
-                    break;
-                }
-                tmp = notes;
-                notes = g_strdup_printf("%s%s%s", tmp, "|Trans type:", dest_string);
-                g_free(tmp);
-            }
+    /* Put everything else in the Notes field */
+    notes = g_strdup_printf("OFX ext. info: ");
 
-            if (data.invtransactiontype_valid == true)
-            {
-                switch (data.invtransactiontype)
-                {
-                case OFX_BUYDEBT:
-                    strncpy(dest_string, "BUYDEBT (Buy debt security)", sizeof(dest_string));
-                    break;
-                case OFX_BUYMF:
-                    strncpy(dest_string, "BUYMF (Buy mutual fund)", sizeof(dest_string));
-                    break;
-                case OFX_BUYOPT:
-                    strncpy(dest_string, "BUYOPT (Buy option)", sizeof(dest_string));
-                    break;
-                case OFX_BUYOTHER:
-                    strncpy(dest_string, "BUYOTHER (Buy other security type)", sizeof(dest_string));
-                    break;
-                case OFX_BUYSTOCK:
-                    strncpy(dest_string, "BUYSTOCK (Buy stock))", sizeof(dest_string));
-                    break;
-                case OFX_CLOSUREOPT:
-                    strncpy(dest_string, "CLOSUREOPT (Close a position for an option)", sizeof(dest_string));
-                    break;
-                case OFX_INCOME:
-                    strncpy(dest_string, "INCOME (Investment income is realized as cash into the investment account)", sizeof(dest_string));
-                    break;
-                case OFX_INVEXPENSE:
-                    strncpy(dest_string, "INVEXPENSE (Misc investment expense that is associated with a specific security)", sizeof(dest_string));
-                    break;
-                case OFX_JRNLFUND:
-                    strncpy(dest_string, "JRNLFUND (Journaling cash holdings between subaccounts within the same investment account)", sizeof(dest_string));
-                    break;
-                case OFX_MARGININTEREST:
-                    strncpy(dest_string, "MARGININTEREST (Margin interest expense)", sizeof(dest_string));
-                    break;
-                case OFX_REINVEST:
-                    strncpy(dest_string, "REINVEST (Reinvestment of income)", sizeof(dest_string));
-                    break;
-                case OFX_RETOFCAP:
-                    strncpy(dest_string, "RETOFCAP (Return of capital)", sizeof(dest_string));
-                    break;
-                case OFX_SELLDEBT:
-                    strncpy(dest_string, "SELLDEBT (Sell debt security.  Used when debt is sold, called, or reached maturity)", sizeof(dest_string));
-                    break;
-                case OFX_SELLMF:
-                    strncpy(dest_string, "SELLMF (Sell mutual fund)", sizeof(dest_string));
-                    break;
-                case OFX_SELLOPT:
-                    strncpy(dest_string, "SELLOPT (Sell option)", sizeof(dest_string));
-                    break;
-                case OFX_SELLOTHER:
-                    strncpy(dest_string, "SELLOTHER (Sell other type of security)", sizeof(dest_string));
-                    break;
-                case OFX_SELLSTOCK:
-                    strncpy(dest_string, "SELLSTOCK (Sell stock)", sizeof(dest_string));
-                    break;
-                case OFX_SPLIT:
-                    strncpy(dest_string, "SPLIT (Stock or mutial fund split)", sizeof(dest_string));
-                    break;
-                case OFX_TRANSFER:
-                    strncpy(dest_string, "TRANSFER (Transfer holdings in and out of the investment account)", sizeof(dest_string));
-                    break;
-                default:
-                    strncpy(dest_string, "ERROR, this investment transaction type is unknown.  This is a bug in ofxdump", sizeof(dest_string));
-                    break;
-                }
-                tmp = notes;
-                notes = g_strdup_printf("%s%s%s", tmp, "|Investment Trans type:", dest_string);
-                g_free(tmp);
-            }
-            if (data.memo_valid == true && data.name_valid == true) /* 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 == true)
-            {
-                Timespec ts;
-                timespecFromTime_t(&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 == true)
-            {
-                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 == true)
-            {
-                tmp = notes;
-                notes = g_strdup_printf("%s%s%ld", tmp, "|Standard Industrial Code:", data.standard_industrial_code);
-                g_free(tmp);
+    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.payee_id_valid == true)
-            {
-                tmp = notes;
-                notes = g_strdup_printf("%s%s%s", tmp, "|Payee ID:", data.payee_id);
-                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;
+        timespecFromTime_t(&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);
 
-            PERR("WRITEME: GnuCash ofx_proc_transaction():Add PAYEE and ADRESS here once supported by libofx!\n");
+    }
+    if (data.payee_id_valid)
+    {
+        tmp = notes;
+        notes = g_strdup_printf("%s%s%s", tmp, "|Payee ID:", data.payee_id);
+        g_free(tmp);
+    }
 
-            /* Ideally, gnucash should process the corrected transactions */
-            if (data.fi_id_corrected_valid == true)
+    //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));
+
+            /* Also put the ofx transaction's memo in the
+             * split's memo field */
+            if (data.memo_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);
+                xaccSplitSetMemo(split, data.memo);
             }
-            xaccTransSetNotes(transaction, notes);
-            g_free(notes);
-            if ( data.account_ptr && data.account_ptr->currency_valid )
+            if (data.fi_id_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);
+                gnc_import_set_split_online_id(split, data.fi_id);
             }
-            else
-            {
-                DEBUG("Currency from libofx unavailable, defaulting to account's default");
-                currency = xaccAccountGetCommodity(account);
-            }
+        }
+        else if (data.unique_id_valid
+                 && data.security_data_valid
+                 && data.security_data_ptr != NULL
+                 && data.security_data_ptr->secname_valid)
+        {
+            /********* Process an investment transaction **********/
+            /* Note that the ACCT_TYPE_STOCK account type
+               should be replaced with something derived from
+               data.invtranstype*/
 
-            xaccTransSetCurrency(transaction, currency);
-            if (data.amount_valid == true)
+            // 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)
             {
-                if (data.invtransactiontype_valid == false)
+                // As we now have the commodity, select the account with that commodity.
+                // @FIXME: Add the automated selection or creation of account here!
+
+                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 = gnc_import_select_account(NULL,
+                                     data.unique_id,
+                                     TRUE,
+                                     investment_account_text,
+                                     investment_commodity,
+                                     ACCT_TYPE_STOCK,
+                                     NULL,
+                                     NULL);
+                if (!investment_account)
                 {
-                    /***** Process a normal transaction ******/
-                    DEBUG("Adding split; Ordinary banking transaction, money flows from or into the source account");
+                    PERR("No investment account found for text: %s\n", investment_account_text);
+                }
+                g_free (investment_account_text);
+                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(account, split);
+                    xaccAccountInsertSplit(investment_account, split);
 
-                    gnc_amount = double_to_gnc_numeric (data.amount,
-                                                        gnc_commodity_get_fraction(xaccTransGetCurrency(transaction)),
-                                                        GNC_HOW_RND_ROUND_HALF_UP);
-                    xaccSplitSetBaseValue(split, gnc_amount, xaccTransGetCurrency(transaction));
+                    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);
 
-                    /* Also put the ofx transaction's memo in the
-                     * split's memo field */
-                    if (data.memo_valid == true)
+                    if (data.security_data_ptr->memo_valid)
                     {
-                        xaccSplitSetMemo(split, data.memo);
+                        xaccSplitSetMemo(split, data.security_data_ptr->memo);
                     }
-                    if (data.fi_id_valid == true)
+                    if (data.fi_id_valid)
                     {
                         gnc_import_set_split_online_id(split, data.fi_id);
                     }
                 }
-                else if (data.unique_id_valid == true
-                         && data.security_data_valid
-                         && data.security_data_ptr != NULL
-                         && data.security_data_ptr->secname_valid == true)
+                else
                 {
-                    /********* Process an investment transaction **********/
-                    /* Note that the ACCT_TYPE_STOCK account type
-                       should be replaced with something derived from
-                       data.invtranstype*/
-                    investment_commodity = gnc_import_select_commodity(data.unique_id,
-                                           0,
-                                           NULL,
-                                           NULL);
-                    if (investment_commodity != NULL)
-                    {
-                        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 = gnc_import_select_account(NULL,
-                                             data.unique_id,
-                                             1,
-                                             investment_account_text,
-                                             investment_commodity,
-                                             ACCT_TYPE_STOCK,
-                                             NULL,
-                                             NULL);
-                        g_free (investment_account_text);
-                        investment_account_text = NULL;
-                        if (investment_account != NULL &&
-                                data.unitprice_valid == true &&
-                                data.units_valid == true &&
-                                ( 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);
+                    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");
+            }
 
-                            gnc_amount = double_to_gnc_numeric (ofx_get_investment_amount(data),
-                                                                gnc_commodity_get_fraction(investment_commodity),
-                                                                GNC_HOW_RND_ROUND_HALF_UP);
-                            gnc_units = double_to_gnc_numeric (data.units,
-                                                               gnc_commodity_get_fraction(investment_commodity),
-                                                               GNC_HOW_RND_ROUND_HALF_UP);
-                            xaccSplitSetAmount(split, gnc_units);
-                            xaccSplitSetValue(split, gnc_amount);
+            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");
 
-                            if (data.security_data_ptr->memo_valid == true)
-                            {
-                                xaccSplitSetMemo(split, data.security_data_ptr->memo);
-                            }
-                            if (data.fi_id_valid == true)
-                            {
-                                gnc_import_set_split_online_id(split, data.fi_id);
-                            }
-                        }
-                        else
-                        {
-                            PERR("The investment account, units or unitprice was not found for the investment transaction");
-                        }
-                    }
-                    else
+                    acc_frame = xaccAccountGetSlots(investment_account);
+                    kvp_val = kvp_frame_get_slot(acc_frame,
+                                                 "ofx/associated-income-account");
+                    if (kvp_val != NULL)
                     {
-                        PERR("Commodity not found for the investment transaction");
+                        income_account = xaccAccountLookup(kvp_value_get_guid(kvp_val), book);
                     }
-
-                    if (data.invtransactiontype_valid == true)
+                    if (income_account == NULL)
                     {
-                        if (data.invtransactiontype == OFX_REINVEST || data.invtransactiontype == OFX_INCOME)
-                        {
-                            DEBUG("Now let's find an account for the destination split");
-
-                            acc_frame = xaccAccountGetSlots(investment_account);
-                            kvp_val = kvp_frame_get_slot(acc_frame,
-                                                         "ofx/associated-income-account");
-                            if (kvp_val != NULL)
-                            {
-                                income_account = xaccAccountLookup(kvp_value_get_guid(kvp_val), book);
-                            }
-                            if (income_account == NULL)
-                            {
-                                DEBUG("Couldn't find an associated income account");
-                                investment_account_text = g_strdup_printf( /* This string is a default account
+                        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(NULL,
-                                                 NULL,
-                                                 1,
-                                                 investment_account_text,
-                                                 currency,
-                                                 ACCT_TYPE_INCOME,
-                                                 NULL,
-                                                 NULL);
-                                income_acc_guid = xaccAccountGetGUID(income_account);
-                                kvp_val = kvp_value_new_guid(income_acc_guid);
-                                if ( acc_frame == NULL)
-                                {
-                                    DEBUG("The kvp_frame was NULL, allocating new one");
-                                    acc_frame = kvp_frame_new();
-                                }
-                                kvp_frame_set_slot_nc(acc_frame, "ofx/associated-income-account",
-                                                      kvp_val);
-                                DEBUG("KVP written");
-
-                            }
-                            else
-                            {
-                                DEBUG("Found at least one associated income account");
-                            }
-                        }
-                        if (income_account != NULL &&
-                                data.invtransactiontype == OFX_REINVEST)
+                                                      _("Income account for security \"%s\""),
+                                                      data.security_data_ptr->secname);
+                        income_account = gnc_import_select_account(NULL,
+                                         NULL,
+                                         1,
+                                         investment_account_text,
+                                         currency,
+                                         ACCT_TYPE_INCOME,
+                                         NULL,
+                                         NULL);
+                        income_acc_guid = xaccAccountGetGUID(income_account);
+                        kvp_val = kvp_value_new_guid(income_acc_guid);
+                        if (acc_frame == NULL)
                         {
-                            DEBUG("Adding investment split; Money flows from the income account");
-                            split = xaccMallocSplit(book);
-                            xaccTransAppendSplit(transaction, split);
-                            xaccAccountInsertSplit(income_account, split);
+                            DEBUG("The kvp_frame was NULL, allocating new one");
+                            acc_frame = kvp_frame_new();
+                        }
+                        kvp_frame_set_slot_nc(acc_frame, "ofx/associated-income-account",
+                                              kvp_val);
+                        DEBUG("KVP written");
 
-                            gnc_amount = double_to_gnc_numeric (data.amount,
-                                                                gnc_commodity_get_fraction(xaccTransGetCurrency(transaction)),
-                                                                GNC_HOW_RND_ROUND_HALF_UP);
-                            xaccSplitSetBaseValue(split, gnc_amount, xaccTransGetCurrency(transaction));
+                    }
+                    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);
 
-                            /* Also put the ofx transaction name in
-                             * the splits memo field, or ofx memo if
-                             * name is unavailable */
-                            if (data.name_valid == true)
-                            {
-                                xaccSplitSetMemo(split, data.name);
-                            }
-                            else if (data.memo_valid == true)
-                            {
-                                xaccSplitSetMemo(split, data.memo);
-                            }
-                        }
-                        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, transaction);
+                    xaccSplitSetBaseValue(split, gnc_amount, xaccTransGetCurrency(transaction));
 
-                            gnc_amount = double_to_gnc_numeric (-data.amount,/*OFX_INCOME amounts come in as positive numbers*/
-                                                                gnc_commodity_get_fraction(xaccTransGetCurrency(transaction)),
-                                                                GNC_HOW_RND_ROUND_HALF_UP);
-                            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);
 
-                            /* Also put the ofx transaction name in
-                             * the splits memo field, or ofx memo if
-                             * name is unavailable */
-                            if (data.name_valid == true)
-                            {
-                                xaccSplitSetMemo(split, data.name);
-                            }
-                            else if (data.memo_valid == true)
-                            {
-                                xaccSplitSetMemo(split, data.memo);
-                            }
-                        }
+                    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 != 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 = double_to_gnc_numeric (-ofx_get_investment_amount(data),
-                                                                gnc_commodity_get_fraction(xaccTransGetCurrency(transaction)),
-                                                                GNC_HOW_RND_ROUND_HALF_UP);
-                            xaccSplitSetBaseValue(split, gnc_amount, xaccTransGetCurrency(transaction));
+                if (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);
 
-                            /* Also put the ofx transaction name in
-                             * the splits memo field, or ofx memo if
-                             * name is unavailable */
-                            if (data.name_valid == true)
-                            {
-                                xaccSplitSetMemo(split, data.name);
-                            }
-                            else if (data.memo_valid == true)
-                            {
-                                xaccSplitSetMemo(split, data.memo);
-                            }
+                    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);
                 }
-
-                /* Use new importer GUI. */
-                DEBUG("%d splits sent to the importer gui", xaccTransCountSplits(transaction));
-                gnc_gen_trans_list_add_trans (gnc_ofx_importer_gui, transaction);
             }
-            else
-            {
-                PERR("The transaction doesn't have a valid amount");
-                xaccTransDestroy(transaction);
-                xaccTransCommitEdit(transaction);
-            }
-
         }
-        else
-        {
-            PERR("Unable to find the account!");
-        }
+
+        /* Use new importer GUI. */
+        DEBUG("%d splits sent to the importer gui", xaccTransCountSplits(transaction));
+        gnc_gen_trans_list_add_trans (gnc_ofx_importer_gui, transaction);
     }
     else
     {
-        PERR("account ID for this transaction is unavailable!");
+        PERR("The transaction doesn't have a valid amount");
+        xaccTransDestroy(transaction);
+        xaccTransCommitEdit(transaction);
     }
+
     return 0;
 }//end ofx_proc_transaction()
 
@@ -686,10 +659,10 @@
     gchar * account_description;
     const gchar * account_type_name = _("Unknown OFX account");
 
-    if (data.account_id_valid == true)
+    if (data.account_id_valid)
     {
         commodity_table = gnc_get_current_commodities ();
-        if ( data.currency_valid == true)
+        if (data.currency_valid)
         {
             DEBUG("Currency from libofx: %s", data.currency);
             default_commodity = gnc_commodity_table_lookup(commodity_table,
@@ -701,7 +674,7 @@
             default_commodity = NULL;
         }
 
-        if (data.account_type_valid == true)
+        if (data.account_type_valid)
         {
             switch (data.account_type)
             {



More information about the gnucash-changes mailing list