r16480 - gnucash/branches/csv-import/src/import-export/csv - Added support for a real "Balance" column;
Benjamin Sperisen
lasindi at cvs.gnucash.org
Thu Aug 30 00:55:37 EDT 2007
Author: lasindi
Date: 2007-08-30 00:55:36 -0400 (Thu, 30 Aug 2007)
New Revision: 16480
Trac: http://svn.gnucash.org/trac/changeset/16480
Modified:
gnucash/branches/csv-import/src/import-export/csv/gnc-csv-import.c
gnucash/branches/csv-import/src/import-export/csv/gnc-csv-model.c
gnucash/branches/csv-import/src/import-export/csv/gnc-csv-model.h
Log:
Added support for a real "Balance" column;
added specific error messages for each row on what error(s) the row had;
a few bug fixes;
added comments;
some refactoring of functions.
Transactions to be imported are also now sorted by date instead of line number.
Modified: gnucash/branches/csv-import/src/import-export/csv/gnc-csv-import.c
===================================================================
--- gnucash/branches/csv-import/src/import-export/csv/gnc-csv-import.c 2007-08-29 22:16:59 UTC (rev 16479)
+++ gnucash/branches/csv-import/src/import-export/csv/gnc-csv-import.c 2007-08-30 04:55:36 UTC (rev 16480)
@@ -68,7 +68,7 @@
GtkEntry* custom_entry; /**< The entry for custom separators */
gboolean encoding_selected_called; /**< Before encoding_selected is first called, this is FALSE.
* (See description of encoding_selected.) */
- /* TODO We might not need previewing_errors. */
+ gboolean not_empty; /**< FALSE initially, true after the first type gnc_csv_preview_update is called. */
gboolean previewing_errors; /**< TRUE if the dialog is displaying
* error lines, instead of all the file
* data. */
@@ -84,7 +84,7 @@
* the user has clicked */
} GncCsvPreview;
-static void gnc_csv_preview_update(GncCsvPreview* preview, gboolean notEmpty);
+static void gnc_csv_preview_update(GncCsvPreview* preview);
/** Event handler for separator changes. This function is called
* whenever one of the widgets for configuring the separators (the
@@ -144,13 +144,18 @@
}
/* If we parsed successfully, redisplay the data. */
- gnc_csv_preview_update(preview, TRUE);
+ gnc_csv_preview_update(preview);
}
-/* TODO Comment */
+/** Event handler for clicking one of the format type radio
+ * buttons. This occurs if the format (Fixed-Width or CSV) is changed.
+ * @param csv_button The "Separated" radio button
+ * @param preview The display of the data being imported
+ */
static void separated_or_fixed_selected(GtkToggleButton* csv_button, GncCsvPreview* preview)
{
GError* error = NULL;
+ /* Set the parsing type correctly. */
if(gtk_toggle_button_get_active(csv_button)) /* If we're in CSV mode ... */
{
stf_parse_options_set_type(preview->parse_data->options, PARSE_TYPE_CSV);
@@ -159,12 +164,17 @@
{
stf_parse_options_set_type(preview->parse_data->options, PARSE_TYPE_FIXED);
}
+
+ /* Reparse the data. */
if(gnc_csv_parse(preview->parse_data, FALSE, &error))
{
+ /* Show an error dialog explaining the problem. */
gnc_error_dialog(NULL, "%s", error->message);
return;
}
- gnc_csv_preview_update(preview, TRUE);
+
+ /* Show the new data. */
+ gnc_csv_preview_update(preview);
}
/** Event handler for a new encoding. This is called when the user
@@ -172,7 +182,7 @@
* user.
* @param selector The widget the user uses to select a new encoding
* @param encoding The encoding that the user selected
- * @param preview The data that is being configured
+ * @param preview The display of the data being imported
*/
static void encoding_selected(GOCharmapSel* selector, const char* encoding,
GncCsvPreview* preview)
@@ -204,7 +214,7 @@
return;
}
- gnc_csv_preview_update(preview, TRUE);
+ gnc_csv_preview_update(preview);
preview->encoding_selected_called = FALSE;
}
else /* If this is the first call of the function ... */
@@ -215,7 +225,7 @@
/** Event handler for selecting a new date format.
* @param format_selector The combo box for selecting date formats
- * @param preview The data that is being configured
+ * @param preview The display of the data being imported
*/
static void date_format_selected(GtkComboBox* format_selector, GncCsvPreview* preview)
{
@@ -226,7 +236,7 @@
* function updates the parse data with the user's column type
* configuration and closes the preview dialog.
* @param widget The "OK" button
- * @param preview The data that is being configured
+ * @param preview The display of the data being imported
*/
static void ok_button_clicked(GtkWidget* widget, GncCsvPreview* preview)
{
@@ -271,7 +281,7 @@
/** Event handler for the "Cancel" button. When the user clicks
* "Cancel", the dialog is simply closed.
* @param widget The "Cancel" button
- * @param preview The data that is being configured
+ * @param preview The display of the data being imported
*/
static void cancel_button_clicked(GtkWidget* widget, GncCsvPreview* preview)
{
@@ -283,7 +293,7 @@
* match.
* @param widget The data treeview
* @param allocation The size of the data treeview
- * @param preview The data that is being configured
+ * @param preview The display of the data being imported
*/
static void treeview_resized(GtkWidget* widget, GtkAllocation* allocation, GncCsvPreview* preview)
{
@@ -315,7 +325,7 @@
* @param renderer The renderer of the column the user changed
* @param path There is only 1 row in preview->ctreeview, so this is always 0.
* @param new_text The text the user selected
- * @param preview The data that is being configured
+ * @param preview The display of the data being imported
*/
static void column_type_edited(GtkCellRenderer* renderer, gchar* path,
gchar* new_text, GncCsvPreview* preview)
@@ -474,6 +484,9 @@
* set it initially to FALSE. */
preview->encoding_selected_called = FALSE;
+ /* It is empty at first. */
+ preview->not_empty = FALSE;
+
return preview;
}
@@ -488,7 +501,7 @@
}
/** Returns the cell renderer from a column in the preview's treeview.
- * @param preview The data that is being configured
+ * @param preview The display of the data being imported
* @param col The number of the column whose cell renderer is being retrieved
* @return The cell renderer of column number col
*/
@@ -584,7 +597,7 @@
gnc_error_dialog(NULL, "%s", error->message);
return FALSE;
}
- gnc_csv_preview_update (preview, TRUE);
+ gnc_csv_preview_update (preview);
}
return TRUE;
@@ -618,7 +631,7 @@
gnc_error_dialog(NULL, "%s", error->message);
return FALSE;
}
- gnc_csv_preview_update (preview, TRUE);
+ gnc_csv_preview_update (preview);
}
return TRUE;
}
@@ -649,7 +662,7 @@
gnc_error_dialog(NULL, "%s", error->message);
return FALSE;
}
- gnc_csv_preview_update (preview, TRUE);
+ gnc_csv_preview_update (preview);
}
return TRUE;
}
@@ -670,7 +683,7 @@
gnc_error_dialog(NULL, "%s", error->message);
return FALSE;
}
- gnc_csv_preview_update (preview, TRUE);
+ gnc_csv_preview_update (preview);
}
return TRUE;
}
@@ -753,8 +766,6 @@
* @param event The event that happened (where the user clicked)
* @param preview The data being configured
*/
-/* TODO Comment */
-/* TODO Clean up */
static void header_button_press_handler(GtkWidget* button, GdkEventButton* event,
GncCsvPreview* preview)
{
@@ -762,6 +773,7 @@
to correct for the indentation of button. */
int i, col = 0, offset = GTK_BIN(button)->child->allocation.x - button->allocation.x,
ncols = preview->parse_data->column_types->len;
+ /* Find the column that was clicked. */
for(i = 0; i < ncols; i++)
{
if(preview->treeview_buttons[i] == button)
@@ -777,10 +789,12 @@
return;
}
+ /* Double clicks can split columns. */
if(event->type == GDK_2BUTTON_PRESS && event->button == 1)
{
make_new_column(preview, col, (int)event->x - offset, FALSE);
}
+ /* Right clicking brings up a context menu. */
else if(event->type == GDK_BUTTON_PRESS && event->button == 3)
{
fixed_context_menu(preview, event, col, (int)event->x - offset);
@@ -793,8 +807,7 @@
* @param preview The data being previewed
* @param notEmpty Whether this function has been called before or not
*/
-/* TODO Look at getting rid of notEmpty */
-static void gnc_csv_preview_update(GncCsvPreview* preview, gboolean notEmpty)
+static void gnc_csv_preview_update(GncCsvPreview* preview)
{
/* store has the data from the file being imported. cstores is an
* array of stores that hold the combo box entries for each
@@ -836,7 +849,7 @@
}
}
- if(notEmpty)
+ if(preview->not_empty)
{
GList *children, *children_begin;
GList *tv_columns, *tv_columns_begin, *ctv_columns, *ctv_columns_begin;
@@ -970,6 +983,9 @@
/* Set the date format to what's in the combo box (since we don't
* necessarily know if this will always be the same). */
preview->parse_data->date_format = gtk_combo_box_get_active(preview->date_format_combo);
+
+ /* It's now been filled with some stuff. */
+ preview->not_empty = TRUE;
}
/** A function that lets the user preview a file's data. This function
@@ -990,7 +1006,7 @@
/* Load the data into the treeview. (This is the first time we've
* called gnc_csv_preview_update on this preview, so we use
* FALSE.) */
- gnc_csv_preview_update(preview, FALSE);
+ gnc_csv_preview_update(preview);
/* Wait until the user clicks "OK" or "Cancel". */
gtk_dialog_run(GTK_DIALOG(preview->dialog));
@@ -1023,12 +1039,11 @@
gtk_widget_show(GTK_WIDGET(instructions_image));
gtk_widget_show(GTK_WIDGET(instructions_label));
- /* TODO Implement */
preview->previewing_errors = TRUE;
preview->approved = FALSE; /* This is FALSE until the user clicks "OK". */
/* Wait until the user clicks "OK" or "Cancel". */
- gnc_csv_preview_update(preview, TRUE);
+ gnc_csv_preview_update(preview);
/* Set the last column to have the header "Errors" so that the user
* doesn't find the extra column confusing. */
@@ -1119,7 +1134,7 @@
}
/* Create transactions from the parsed data. */
- gnc_parse_to_trans(parse_data, account, FALSE);
+ gnc_csv_parse_to_trans(parse_data, account, FALSE);
/* If there are errors, let the user try and eliminate them by
* previewing them. Repeat until either there are no errors or the
@@ -1127,7 +1142,7 @@
while(!((parse_data->error_lines == NULL) || user_canceled))
{
user_canceled = gnc_csv_preview_errors(preview);
- gnc_parse_to_trans(parse_data, account, TRUE);
+ gnc_csv_parse_to_trans(parse_data, account, TRUE);
}
/* Create the genereic transaction importer GUI. */
Modified: gnucash/branches/csv-import/src/import-export/csv/gnc-csv-model.c
===================================================================
--- gnucash/branches/csv-import/src/import-export/csv/gnc-csv-model.c 2007-08-29 22:16:59 UTC (rev 16479)
+++ gnucash/branches/csv-import/src/import-export/csv/gnc-csv-model.c 2007-08-30 04:55:36 UTC (rev 16480)
@@ -33,7 +33,8 @@
N_("Description"),
N_("Balance"),
N_("Deposit"),
- N_("Withdrawal")};
+ N_("Withdrawal"),
+ N_("Num")};
/** A set of sensible defaults for parsing CSV files.
* @return StfParseOptions_t* for parsing a file with comma separators
@@ -470,7 +471,6 @@
* @error error Will contain an error if there is a failure
* @return 0 on success, 1 on failure
*/
-/* TODO Should we use 0 for domain and code in errors? */
int gnc_csv_parse(GncCsvParseData* parse_data, gboolean guessColTypes, GError** error)
{
/* max_cols is the number of columns in the row with the most columns. */
@@ -498,6 +498,7 @@
/* Record the original row lengths of parse_data->orig_lines. */
if(parse_data->orig_row_lengths != NULL)
g_array_free(parse_data->orig_row_lengths, FALSE);
+
parse_data->orig_row_lengths =
g_array_sized_new(FALSE, FALSE, sizeof(int), parse_data->orig_lines->len);
g_array_set_size(parse_data->orig_row_lengths, parse_data->orig_lines->len);
@@ -628,6 +629,7 @@
return *((time_t*)(prop->value)) != -1;
case GNC_CSV_DESCRIPTION:
+ case GNC_CSV_NUM:
prop->value = g_strdup(str);
return TRUE;
@@ -673,9 +675,9 @@
if(abs(value) > 0.00001)
{
prop->value = g_new(gnc_numeric, 1);
- *((gnc_numeric*)(prop->value)) = double_to_gnc_numeric(value,
- xaccAccountGetCommoditySCU(prop->list->account),
- GNC_RND_ROUND);
+ *((gnc_numeric*)(prop->value)) =
+ double_to_gnc_numeric(value, xaccAccountGetCommoditySCU(prop->list->account),
+ GNC_RND_ROUND);
}
return TRUE;
}
@@ -723,8 +725,6 @@
}
/** Adds a split to a transaction.
- * This function is only called by trans_property_list_to_trans. This is in a
- * separate function to avoid copying code twice in trans_property_list_to_trans.
* @param trans The transaction to add a split to
* @param account The account used for the split
* @param book The book where the split should be stored
@@ -834,26 +834,41 @@
/** Create a Transaction from a TransPropertyList.
* @param list The list of properties
* @param error Contains an error on failure
- * @return On success, a pointer to a new transaction; on failure, NULL
+ * @return On success, a GncCsvTransLine; on failure, the trans pointer is NULL
*/
-/* TODO Comment */
-static Transaction* trans_property_list_to_trans(TransPropertyList* list, gchar** error)
+static GncCsvTransLine* trans_property_list_to_trans(TransPropertyList* list, gchar** error)
{
- Transaction* trans;
+ GncCsvTransLine* trans_line = g_new(GncCsvTransLine, 1);
GList* properties_begin = list->properties;
GNCBook* book = gnc_account_get_book(list->account);
gnc_commodity* currency = xaccAccountGetCommodity(list->account);
- gnc_numeric amount;
- gboolean noAmountYet = TRUE;
-
+ gnc_numeric amount = double_to_gnc_numeric(0.0, xaccAccountGetCommoditySCU(list->account),
+ GNC_RND_ROUND);
+
+ /* This flag is set to TRUE if we can use the "Deposit" or "Withdrawal" column. */
+ gboolean amount_set = FALSE;
+
+ /* The balance is 0 by default. */
+ trans_line->balance_set = FALSE;
+ trans_line->balance = amount;
+
+ /* We make the line_no -1 just to mark that it hasn't been set. We
+ * may get rid of line_no soon anyway, so it's not particularly
+ * important. */
+ trans_line->line_no = -1;
+
+ /* Make sure this is a transaction with all the columns we need. */
if(!trans_property_list_verify_essentials(list, error))
+ {
+ g_free(trans_line);
return NULL;
+ }
- trans = xaccMallocTransaction(book);
-
- xaccTransBeginEdit(trans);
- xaccTransSetCurrency(trans, currency);
+ trans_line->trans = xaccMallocTransaction(book);
+ xaccTransBeginEdit(trans_line->trans);
+ xaccTransSetCurrency(trans_line->trans, currency);
+ /* Go through each of the properties and edit the transaction accordingly. */
list->properties = properties_begin;
while(list->properties != NULL)
{
@@ -861,39 +876,60 @@
switch(prop->type)
{
case GNC_CSV_DATE:
- xaccTransSetDatePostedSecs(trans, *((time_t*)(prop->value)));
+ xaccTransSetDatePostedSecs(trans_line->trans, *((time_t*)(prop->value)));
break;
case GNC_CSV_DESCRIPTION:
- xaccTransSetDescription(trans, (char*)(prop->value));
+ xaccTransSetDescription(trans_line->trans, (char*)(prop->value));
break;
- case GNC_CSV_DEPOSIT:
- case GNC_CSV_WITHDRAWAL:
- case GNC_CSV_BALANCE:
- if(noAmountYet && prop->value != NULL)
+ case GNC_CSV_NUM:
+ xaccTransSetNum(trans_line->trans, (char*)(prop->value));
+ break;
+
+ case GNC_CSV_DEPOSIT: /* Add deposits to the existing amount. */
+ if(prop->value != NULL)
{
- /* Withdrawals are just negative deposits. */
- if(prop->type == GNC_CSV_WITHDRAWAL)
- amount = gnc_numeric_neg(*((gnc_numeric*)(prop->value)));
- else
- amount = *((gnc_numeric*)(prop->value));
+ amount = gnc_numeric_add(*((gnc_numeric*)(prop->value)),
+ amount,
+ xaccAccountGetCommoditySCU(list->account),
+ GNC_RND_ROUND);
+ amount_set = TRUE;
+ /* We will use the "Deposit" and "Withdrawal" columns in preference to "Balance". */
+ trans_line->balance_set = FALSE;
+ }
+ break;
- trans_add_split(trans, list->account, book, amount);
-
- noAmountYet = FALSE;
+ case GNC_CSV_WITHDRAWAL: /* Withdrawals are just negative deposits. */
+ if(prop->value != NULL)
+ {
+ amount = gnc_numeric_add(gnc_numeric_neg(*((gnc_numeric*)(prop->value))),
+ amount,
+ xaccAccountGetCommoditySCU(list->account),
+ GNC_RND_ROUND);
+ amount_set = TRUE;
+ /* We will use the "Deposit" and "Withdrawal" columns in preference to "Balance". */
+ trans_line->balance_set = FALSE;
}
+ break;
+
+ case GNC_CSV_BALANCE: /* The balance gets stored in a separate field in trans_line. */
+ /* We will use the "Deposit" and "Withdrawal" columns in preference to "Balance". */
+ if(!amount_set && prop->value != NULL)
+ {
+ /* This gets put into the actual transaction at the end of gnc_csv_parse_to_trans. */
+ trans_line->balance = *((gnc_numeric*)(prop->value));
+ trans_line->balance_set = TRUE;
+ }
+ break;
}
list->properties = g_list_next(list->properties);
}
- if(noAmountYet)
- {
- amount = double_to_gnc_numeric(0.0, xaccAccountGetCommoditySCU(list->account), GNC_RND_ROUND);
- trans_add_split(trans, list->account, book, amount);
- }
+ /* Add a split with the cumulative amount value. */
+ trans_add_split(trans_line->trans, list->account, book, amount);
- return trans;
+ return trans_line;
}
/** Creates a list of transactions from parsed data. Transactions that
@@ -906,12 +942,16 @@
* @param redo_errors TRUE to convert only error data, FALSE for all data
* @return 0 on success, 1 on failure
*/
-int gnc_parse_to_trans(GncCsvParseData* parse_data, Account* account,
- gboolean redo_errors)
+int gnc_csv_parse_to_trans(GncCsvParseData* parse_data, Account* account,
+ gboolean redo_errors)
{
+ gboolean hasBalanceColumn;
int i, j, max_cols = 0;
GArray* column_types = parse_data->column_types;
GList *error_lines = NULL, *begin_error_lines = NULL;
+
+ /* last_transaction points to the last element in
+ * parse_data->transactions, or NULL if it's empty. */
GList* last_transaction = NULL;
/* Free parse_data->error_lines and parse_data->transactions if they
@@ -920,15 +960,34 @@
{
begin_error_lines = error_lines = parse_data->error_lines;
}
- else if(parse_data->error_lines != NULL)
+ else
{
- g_list_free(parse_data->error_lines);
+ if(parse_data->error_lines != NULL)
+ {
+ g_list_free(parse_data->error_lines);
+ }
+ if(parse_data->transactions != NULL)
+ {
+ g_list_free(parse_data->transactions);
+ }
}
parse_data->error_lines = NULL;
if(redo_errors) /* If we're looking only at error data ... */
{
- last_transaction = parse_data->transactions;
+ if(parse_data->transactions == NULL)
+ {
+ last_transaction = NULL;
+ }
+ else
+ {
+ /* Move last_transaction to the end. */
+ last_transaction = parse_data->transactions;
+ while(g_list_next(last_transaction) != NULL)
+ {
+ last_transaction = g_list_next(last_transaction);
+ }
+ }
/* ... we use only the lines in error_lines. */
if(error_lines == NULL)
i = parse_data->orig_lines->len; /* Don't go into the for loop. */
@@ -940,6 +999,7 @@
/* The following while-loop effectively behaves like the following for-loop:
* for(i = 0; i < parse_data->orig_lines->len; i++). */
i = 0;
+ last_transaction = NULL;
}
while(i < parse_data->orig_lines->len)
{
@@ -948,11 +1008,8 @@
gboolean errors = FALSE;
gchar* error_message = NULL;
TransPropertyList* list = trans_property_list_new(account, parse_data->date_format);
- Transaction* trans = NULL;
+ GncCsvTransLine* trans_line;
- /* TODO There should eventually be a specification of what errors
- * actually occurred, not just that one happened. */
-
for(j = 0; j < line->len; j++)
{
/* We do nothing in "None" columns. */
@@ -980,8 +1037,8 @@
/* If we had success, add the transaction to parse_data->transaction. */
if(!errors)
{
- trans = trans_property_list_to_trans(list, &error_message);
- errors = trans == NULL;
+ trans_line = trans_property_list_to_trans(list, &error_message);
+ errors = trans_line == NULL;
}
trans_property_list_free(list);
@@ -1006,26 +1063,41 @@
else
{
/* If all went well, add this transaction to the list. */
- GncCsvTransLine* trans_line = g_new(GncCsvTransLine, 1);
-
- trans_line->trans = trans;
trans_line->line_no = i;
- if(redo_errors)
+ /* We keep the transactions sorted by date. We start at the end
+ * of the list and go backward, simply because the file itself
+ * is probably also sorted by date (but we need to handle the
+ * exception anyway). */
+
+ /* If we can just put it at the end, do so and increment last_transaction. */
+ if(last_transaction == NULL ||
+ xaccTransGetDate(((GncCsvTransLine*)(last_transaction->data))->trans) <= xaccTransGetDate(trans_line->trans))
{
- /* If we are correcting errors, find the right place to insert
- * the transaction. */
- while(last_transaction != NULL &&
- ((GncCsvTransLine*)(last_transaction->data))->line_no < i)
- {
+ parse_data->transactions = g_list_append(parse_data->transactions, trans_line);
+ /* If this is the first transaction, we need to get last_transaction on track. */
+ if(last_transaction == NULL)
+ last_transaction = parse_data->transactions;
+ else /* Otherwise, we can just continue. */
last_transaction = g_list_next(last_transaction);
- }
- parse_data->transactions =
- g_list_insert_before(parse_data->transactions, last_transaction, trans_line);
}
+ /* Otherwise, search backward for the correct spot. */
else
{
- parse_data->transactions = g_list_append(parse_data->transactions, trans_line);
+ GList* insertion_spot = last_transaction;
+ while(insertion_spot != NULL &&
+ xaccTransGetDate(((GncCsvTransLine*)(insertion_spot->data))->trans) > xaccTransGetDate(trans_line->trans))
+ {
+ insertion_spot = g_list_previous(insertion_spot);
+ }
+ /* Move insertion_spot one location forward since we have to
+ * use the g_list_insert_before function. */
+ if(insertion_spot == NULL) /* We need to handle the case of inserting at the beginning of the list. */
+ insertion_spot = parse_data->transactions;
+ else
+ insertion_spot = g_list_next(insertion_spot);
+
+ parse_data->transactions = g_list_insert_before(parse_data->transactions, insertion_spot, trans_line);
}
}
@@ -1044,8 +1116,69 @@
i++;
}
}
- if(redo_errors)
+
+ /* If we have a balance column, set the appropriate amounts on the transactions. */
+ hasBalanceColumn = FALSE;
+ for(i = 0; i < parse_data->column_types->len; i++)
{
+ if(parse_data->column_types->data[i] == GNC_CSV_BALANCE)
+ {
+ hasBalanceColumn = TRUE;
+ break;
+ }
+ }
+
+ if(hasBalanceColumn)
+ {
+ GList* transactions = parse_data->transactions;
+
+ /* balance_offset is how much the balance currently in the account
+ * differs from what it will be after the transactions are
+ * imported. This will be sum of all the previous transactions for
+ * any given transaction. */
+ gnc_numeric balance_offset = double_to_gnc_numeric(0.0,
+ xaccAccountGetCommoditySCU(account),
+ GNC_RND_ROUND);
+ while(transactions != NULL)
+ {
+ GncCsvTransLine* trans_line = (GncCsvTransLine*)transactions->data;
+ if(trans_line->balance_set)
+ {
+ time_t date = xaccTransGetDate(trans_line->trans);
+ /* Find what the balance should be by adding the offset to the actual balance. */
+ gnc_numeric existing_balance = gnc_numeric_add(balance_offset,
+ xaccAccountGetBalanceAsOfDate(account, date),
+ xaccAccountGetCommoditySCU(account),
+ GNC_RND_ROUND);
+
+ /* The amount of the transaction is the difference between the new and existing balance. */
+ gnc_numeric amount = gnc_numeric_sub(trans_line->balance,
+ existing_balance,
+ xaccAccountGetCommoditySCU(account),
+ GNC_RND_ROUND);
+
+ SplitList* splits = xaccTransGetSplitList(trans_line->trans);
+ while(splits)
+ {
+ SplitList* next_splits = g_list_next(splits);
+ xaccSplitDestroy((Split*)splits->data);
+ splits = next_splits;
+ }
+
+ trans_add_split(trans_line->trans, account, gnc_account_get_book(account), amount);
+
+ /* This new transaction needs to be added to the balance offset. */
+ balance_offset = gnc_numeric_add(balance_offset,
+ amount,
+ xaccAccountGetCommoditySCU(account),
+ GNC_RND_ROUND);
+ }
+ transactions = g_list_next(transactions);
+ }
+ }
+
+ if(redo_errors) /* Now that we're at the end, we do the freeing. */
+ {
g_list_free(begin_error_lines);
}
Modified: gnucash/branches/csv-import/src/import-export/csv/gnc-csv-model.h
===================================================================
--- gnucash/branches/csv-import/src/import-export/csv/gnc-csv-model.h 2007-08-29 22:16:59 UTC (rev 16479)
+++ gnucash/branches/csv-import/src/import-export/csv/gnc-csv-model.h 2007-08-30 04:55:36 UTC (rev 16480)
@@ -44,6 +44,7 @@
GNC_CSV_BALANCE,
GNC_CSV_DEPOSIT,
GNC_CSV_WITHDRAWAL,
+ GNC_CSV_NUM,
GNC_CSV_NUM_COL_TYPES};
/** Enumeration for error types. These are the different types of
@@ -61,6 +62,9 @@
char* end;
} GncCsvStr;
+/* TODO We now sort transactions by date, not line number, so we
+ * should probably get rid of this struct and uses of it. */
+
/** Struct pairing a transaction with a line number. This struct is
* used to keep the transactions in order. When rows are separated
* into "valid" and "error" lists (in case some of the rows have cells
@@ -72,6 +76,8 @@
{
int line_no;
Transaction* trans;
+ gnc_numeric balance; /**< The (supposed) balance after this transaction takes place */
+ gboolean balance_set; /**< TRUE if balance has been set from user data, FALSE otherwise */
} GncCsvTransLine;
extern const int num_date_formats;
@@ -111,6 +117,6 @@
int gnc_csv_parse(GncCsvParseData* parse_data, gboolean guessColTypes, GError** error);
-int gnc_parse_to_trans(GncCsvParseData* parse_data, Account* account, gboolean redo_errors);
+int gnc_csv_parse_to_trans(GncCsvParseData* parse_data, Account* account, gboolean redo_errors);
#endif
More information about the gnucash-changes
mailing list