gnucash master: Multiple changes pushed

Geert Janssens gjanssens at code.gnucash.org
Tue Feb 14 12:21:33 EST 2023


Updated	 via  https://github.com/Gnucash/gnucash/commit/a982b60f (commit)
	 via  https://github.com/Gnucash/gnucash/commit/6993fed2 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/dae07fba (commit)
	 via  https://github.com/Gnucash/gnucash/commit/1d971c15 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/545f27c5 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/aa0a68fd (commit)
	 via  https://github.com/Gnucash/gnucash/commit/be0579dc (commit)
	 via  https://github.com/Gnucash/gnucash/commit/9df059e9 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/c6a93903 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/003f379d (commit)
	 via  https://github.com/Gnucash/gnucash/commit/9e1268d9 (commit)
	from  https://github.com/Gnucash/gnucash/commit/232dd765 (commit)



commit a982b60f17f7b4af90db72148e46159a06feb6f5
Merge: 232dd7656 6993fed22
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Tue Feb 14 18:21:24 2023 +0100

    Merge branch 'CsvTransImpExp'


commit 6993fed22974d2465b8507c40b728bb526a7da0b
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Tue Feb 14 17:58:05 2023 +0100

    CsvTransExp - fix info message to match state of simple format button

diff --git a/gnucash/import-export/csv-exp/assistant-csv-export.c b/gnucash/import-export/csv-exp/assistant-csv-export.c
index 1082445a7..d71b17a44 100644
--- a/gnucash/import-export/csv-exp/assistant-csv-export.c
+++ b/gnucash/import-export/csv-exp/assistant-csv-export.c
@@ -262,10 +262,16 @@ csv_export_simple_cb (GtkToggleButton *button, gpointer user_data)
 {
     CsvExportInfo *info = user_data;
 
-    if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(button)))
-        info->simple_layout = TRUE;
+    info->simple_layout = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON(button));
+
+    gchar *msg = NULL;
+    if (info->simple_layout)
+        msg = g_strdup_printf (_(start_trans_common_string), _(start_trans_simple_string));
     else
-        info->simple_layout = FALSE;
+        msg = g_strdup_printf (_(start_trans_common_string), _(start_trans_multi_string));
+
+    gtk_label_set_text (GTK_LABEL(info->start_label), msg);
+    g_free (msg);
 }
 
 /*******************************************************
@@ -659,25 +665,15 @@ csv_export_assistant_start_page_prepare (GtkAssistant *assistant,
         gpointer user_data)
 {
     CsvExportInfo *info = user_data;
+    gchar *msg = NULL;
 
-
-
-    /* Set Start page text */
     if (info->export_type == XML_EXPORT_TREE)
-        gtk_label_set_text (GTK_LABEL(info->start_label), gettext (start_tree_string));
+        msg = g_strdup (_(start_tree_string));
     else
-    {
-        gchar *label_string = NULL;
-        /* General Journal and search registers are always multi-line exported */
-        if ((info->export_type == XML_EXPORT_REGISTER) &&
-            (g_list_length (info->csva.account_list) == 0))
-            label_string = g_strdup_printf (_(start_trans_common_string), _(start_trans_multi_string));
-        else
-            label_string = g_strdup_printf (_(start_trans_common_string), _(start_trans_simple_string));
+        msg = g_strdup_printf (_(start_trans_common_string), _(start_trans_multi_string));
 
-        gtk_label_set_text (GTK_LABEL(info->start_label), label_string);
-        g_free (label_string);
-    }
+    gtk_label_set_text (GTK_LABEL(info->start_label), msg);
+    g_free (msg);
 
     /* Enable the Assistant Buttons */
     gtk_assistant_set_page_complete (assistant, info->start_page, TRUE);
diff --git a/gnucash/import-export/csv-exp/assistant-csv-export.h b/gnucash/import-export/csv-exp/assistant-csv-export.h
index 7079b4928..a2cf8f299 100644
--- a/gnucash/import-export/csv-exp/assistant-csv-export.h
+++ b/gnucash/import-export/csv-exp/assistant-csv-export.h
@@ -73,7 +73,6 @@ typedef struct
     CsvExportAcc    csva;
 
     Query          *query;
-    Account        *account;
 
     GtkWidget      *start_page;
     GtkWidget      *account_page;

commit dae07fba993c21b55607404a99d890e91c96b1dc
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Tue Feb 14 17:32:52 2023 +0100

    CsvTransExp - treat single account as list of accounts with one element
    
    That allows to remove another tracking variable.

diff --git a/gnucash/import-export/csv-exp/assistant-csv-export.c b/gnucash/import-export/csv-exp/assistant-csv-export.c
index d2f11b44d..1082445a7 100644
--- a/gnucash/import-export/csv-exp/assistant-csv-export.c
+++ b/gnucash/import-export/csv-exp/assistant-csv-export.c
@@ -95,7 +95,7 @@ static const gchar *start_trans_common_string = N_(
             "Select the settings you require for the file and then click \"Next\" "
             "to proceed or \"Cancel\" to abort the export.\n");
 
-static const gchar *start_trans__multi_string = N_(
+static const gchar *start_trans_multi_string = N_(
             "There will be multiple rows for each transaction with each row "
             "representing one split.");
 
@@ -669,8 +669,9 @@ csv_export_assistant_start_page_prepare (GtkAssistant *assistant,
     {
         gchar *label_string = NULL;
         /* General Journal and search registers are always multi-line exported */
-        if ((info->export_type == XML_EXPORT_REGISTER) && (info->account == NULL))
-            label_string = g_strdup_printf (_(start_trans_common_string), _(start_trans__multi_string));
+        if ((info->export_type == XML_EXPORT_REGISTER) &&
+            (g_list_length (info->csva.account_list) == 0))
+            label_string = g_strdup_printf (_(start_trans_common_string), _(start_trans_multi_string));
         else
             label_string = g_strdup_printf (_(start_trans_common_string), _(start_trans_simple_string));
 
@@ -725,7 +726,8 @@ csv_export_assistant_finish_page_prepare (GtkAssistant *assistant,
         text = g_strdup_printf (gettext (finish_tree_string), info->file_name);
     else
     {
-        if ((info->export_type == XML_EXPORT_REGISTER) && (info->account == NULL))
+        if ((info->export_type == XML_EXPORT_REGISTER) &&
+            (g_list_length (info->csva.account_list) == 0))
             text = g_strdup_printf (gettext (finish_trans_search_gl_string), info->file_name);
         else
             text = g_strdup_printf (gettext (finish_trans_string),
@@ -880,7 +882,8 @@ csv_export_assistant_create (CsvExportInfo *info)
         GtkWidget *chkbox = GTK_WIDGET(gtk_builder_get_object(builder, "simple_layout"));
 
         // Don't provide simple export layout for search registers and General Journal
-        if ((info->export_type == XML_EXPORT_TREE) || (info->account == NULL))
+        if ((info->export_type == XML_EXPORT_TREE) ||
+            (g_list_length (info->csva.account_list) == 0))
             gtk_widget_destroy (chkbox);
         gtk_assistant_remove_page (GTK_ASSISTANT(info->assistant), 1); //remove accounts page
     }
@@ -1012,8 +1015,6 @@ gnc_file_csv_export_internal (CsvExportType export_type, Query *q, Account *acc)
     if (q)
         info->query = q;
     if (acc)
-        info->account = acc;
-    if ((export_type == XML_EXPORT_REGISTER) && acc)
         info->csva.account_list = g_list_prepend(info->csva.account_list, acc);
 
     csv_export_assistant_create (info);

commit 1d971c157887e81afc2720edec8f90a0e6cfa6ff
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Tue Feb 14 17:24:11 2023 +0100

    CsvTransExp - remove redundant counter num_accounts
    
    Simply use length of account list instead

diff --git a/gnucash/import-export/csv-exp/assistant-csv-export.c b/gnucash/import-export/csv-exp/assistant-csv-export.c
index 0e42719ad..d2f11b44d 100644
--- a/gnucash/import-export/csv-exp/assistant-csv-export.c
+++ b/gnucash/import-export/csv-exp/assistant-csv-export.c
@@ -378,7 +378,7 @@ show_acct_type_accounts (CsvExportInfo *info)
  *
  * update the account tree
  *******************************************************/
-static int
+static void
 update_accounts_tree (CsvExportInfo *info)
 {
     GncTreeViewAccount *tree;
@@ -396,8 +396,6 @@ update_accounts_tree (CsvExportInfo *info)
     string = g_strdup_printf ("%d", num_accounts);
     gtk_label_set_text (GTK_LABEL (label), string);
     g_free (string);
-
-    return num_accounts;
 }
 
 
@@ -410,22 +408,22 @@ static void
 csv_export_account_changed_cb (GtkTreeSelection *selection,
                                gpointer user_data)
 {
-    CsvExportInfo *info = user_data;
-    GtkAssistant *assistant = GTK_ASSISTANT(info->assistant);
-    GncTreeViewAccount *view;
 
     g_return_if_fail(GTK_IS_TREE_SELECTION(selection));
 
-    info->csva.num_accounts = update_accounts_tree (info);
+    CsvExportInfo *info = user_data;
+
+    GncTreeViewAccount *view = GNC_TREE_VIEW_ACCOUNT(info->csva.account_treeview);
+    info->csva.account_list = gnc_tree_view_account_get_selected_accounts (view);
 
     /* Enable the "Next" Assistant Button if we have accounts */
-    if (info->csva.num_accounts > 0)
+    GtkAssistant *assistant = GTK_ASSISTANT(info->assistant);
+    if (g_list_length (info->csva.account_list) > 0)
         gtk_assistant_set_page_complete (assistant, info->account_page, TRUE);
     else
         gtk_assistant_set_page_complete (assistant, info->account_page, FALSE);
 
-    view = GNC_TREE_VIEW_ACCOUNT(info->csva.account_treeview);
-    info->csva.account_list = gnc_tree_view_account_get_selected_accounts (view);
+    update_accounts_tree (info);
 }
 
 
@@ -692,7 +690,7 @@ csv_export_assistant_account_page_prepare (GtkAssistant *assistant,
     CsvExportInfo *info = user_data;
 
     /* Enable the "Next" Assistant Button if we have accounts */
-    if (info->csva.num_accounts > 0)
+    if (g_list_length(info->csva.account_list) > 0)
         gtk_assistant_set_page_complete (assistant, info->account_page, TRUE);
     else
         gtk_assistant_set_page_complete (assistant, info->account_page, FALSE);
@@ -730,7 +728,9 @@ csv_export_assistant_finish_page_prepare (GtkAssistant *assistant,
         if ((info->export_type == XML_EXPORT_REGISTER) && (info->account == NULL))
             text = g_strdup_printf (gettext (finish_trans_search_gl_string), info->file_name);
         else
-            text = g_strdup_printf (gettext (finish_trans_string), info->file_name, info->csva.num_accounts);
+            text = g_strdup_printf (gettext (finish_trans_string),
+                                    info->file_name,
+                                    g_list_length (info->csva.account_list));
     }
     gtk_label_set_text (GTK_LABEL(info->finish_label), text);
     g_free (text);
@@ -802,6 +802,7 @@ csv_export_assistant_destroy_cb (GtkWidget *object, gpointer user_data)
 {
     CsvExportInfo *info = user_data;
     gnc_unregister_gui_component_by_data (ASSISTANT_CSV_EXPORT_CM_CLASS, info);
+    g_list_free (info->csva.account_list);
     g_free (info);
 }
 
@@ -1013,7 +1014,7 @@ gnc_file_csv_export_internal (CsvExportType export_type, Query *q, Account *acc)
     if (acc)
         info->account = acc;
     if ((export_type == XML_EXPORT_REGISTER) && acc)
-        info->csva.num_accounts = 1;
+        info->csva.account_list = g_list_prepend(info->csva.account_list, acc);
 
     csv_export_assistant_create (info);
     gnc_register_gui_component (ASSISTANT_CSV_EXPORT_CM_CLASS,
diff --git a/gnucash/import-export/csv-exp/assistant-csv-export.h b/gnucash/import-export/csv-exp/assistant-csv-export.h
index bb52e4423..7079b4928 100644
--- a/gnucash/import-export/csv-exp/assistant-csv-export.h
+++ b/gnucash/import-export/csv-exp/assistant-csv-export.h
@@ -62,7 +62,6 @@ typedef struct
     GtkWidget        *select_button;
     GtkWidget        *num_acct_label;
     GList            *account_list;
-    int               num_accounts;
     GNCAccountType    account_type;
 } CsvExportAcc;
 
diff --git a/gnucash/import-export/csv-exp/csv-transactions-export.c b/gnucash/import-export/csv-exp/csv-transactions-export.c
index 82d998235..20dde3dcb 100644
--- a/gnucash/import-export/csv-exp/csv-transactions-export.c
+++ b/gnucash/import-export/csv-exp/csv-transactions-export.c
@@ -578,19 +578,13 @@ void csv_transactions_export (CsvExportInfo *info)
     if (info->failed)
         return;
 
-    if (info->export_type == XML_EXPORT_TRANS)
+    /* Go through list of accounts */
+    for (GList *ptr = info->csva.account_list; ptr; ptr = g_list_next(ptr))
     {
-        /* Go through list of accounts */
-        for (GList *ptr = info->csva.account_list; ptr; ptr = g_list_next(ptr))
-        {
-            Account *acc = ptr->data;
-            DEBUG("Account being processed is : %s", xaccAccountGetName (acc));
-            account_splits (info, acc, fh);
-        }
-        g_list_free (info->csva.account_list);
+        Account *acc = ptr->data;
+        DEBUG("Account being processed is : %s", xaccAccountGetName (acc));
+        account_splits (info, acc, fh);
     }
-    else
-        account_splits (info, info->account, fh);
 
     fclose (fh);
     LEAVE("");

commit 545f27c5500a4bb3e1068c629c3ed89251ce9704
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Tue Feb 14 16:52:13 2023 +0100

    CsvTransExp - limit scope of variable to actual use

diff --git a/gnucash/import-export/csv-exp/assistant-csv-export.c b/gnucash/import-export/csv-exp/assistant-csv-export.c
index 72c4d565e..0e42719ad 100644
--- a/gnucash/import-export/csv-exp/assistant-csv-export.c
+++ b/gnucash/import-export/csv-exp/assistant-csv-export.c
@@ -303,7 +303,6 @@ load_settings (CsvExportInfo *info)
     info->separator_str = ",";
     info->file_name = NULL;
     info->starting_dir = NULL;
-    info->trans_list = NULL;
 
     /* The default directory for the user to select files. */
     info->starting_dir = gnc_get_default_directory (GNC_PREFS_GROUP);
diff --git a/gnucash/import-export/csv-exp/assistant-csv-export.h b/gnucash/import-export/csv-exp/assistant-csv-export.h
index 9cb1f9af0..bb52e4423 100644
--- a/gnucash/import-export/csv-exp/assistant-csv-export.h
+++ b/gnucash/import-export/csv-exp/assistant-csv-export.h
@@ -72,7 +72,6 @@ typedef struct
     CsvExportType   export_type;
     CsvExportDate   csvd;
     CsvExportAcc    csva;
-    GList          *trans_list;
 
     Query          *query;
     Account        *account;
diff --git a/gnucash/import-export/csv-exp/csv-transactions-export.c b/gnucash/import-export/csv-exp/csv-transactions-export.c
index 2244a259c..82d998235 100644
--- a/gnucash/import-export/csv-exp/csv-transactions-export.c
+++ b/gnucash/import-export/csv-exp/csv-transactions-export.c
@@ -438,13 +438,14 @@ void account_splits (CsvExportInfo *info, Account *acc, FILE *fh )
     }
 
     /* Run the query */
+    GList *trans_list = NULL;
     for (GList *splits = qof_query_run (info->query); splits; splits = splits->next)
     {
         Split *split = splits->data;
 
         // Look for trans already exported in trans_list
         Transaction *trans = xaccSplitGetParent (split);
-        if (g_list_find (info->trans_list, trans))
+        if (g_list_find (trans_list, trans))
             continue;
 
         // Look for blank split
@@ -498,11 +499,12 @@ void account_splits (CsvExportInfo *info, Account *acc, FILE *fh )
             if (info->failed)
                 break;
         }
-        info->trans_list = g_list_prepend (info->trans_list, trans); // add trans to trans_list
+        trans_list = g_list_prepend (trans_list, trans);
     }
 
     if (info->export_type == XML_EXPORT_TRANS)
         qof_query_destroy (info->query);
+    g_list_free (trans_list);
 }
 
 
@@ -590,8 +592,6 @@ void csv_transactions_export (CsvExportInfo *info)
     else
         account_splits (info, info->account, fh);
 
-    g_list_free (info->trans_list); // free trans_list
-
     fclose (fh);
     LEAVE("");
 }

commit aa0a68fd1c67c0e0aed21e2193ecf35107745dcc
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Tue Feb 14 16:47:18 2023 +0100

    CsvTransExp - repeat transaction details on every line in multi-line mode
    
    The GnuCash Csv Importer can deal with both cases,
    but there has been user feedback that the format
    with only the first line displaying transaction
    details is confusing and/or not readily usable
    in external tools.

diff --git a/gnucash/import-export/csv-exp/csv-transactions-export.c b/gnucash/import-export/csv-exp/csv-transactions-export.c
index 75ea0beed..2244a259c 100644
--- a/gnucash/import-export/csv-exp/csv-transactions-export.c
+++ b/gnucash/import-export/csv-exp/csv-transactions-export.c
@@ -379,8 +379,20 @@ make_simple_trans_line (Transaction *trans, Split *split, CsvExportInfo *info)
 }
 
 static gchar*
-make_split_part (gchar* exp_line, Split *split, bool t_void, CsvExportInfo *info)
+make_complex_trans_line (Transaction *trans, Split *split, CsvExportInfo *info)
 {
+    // Transaction fields
+    gchar *exp_line = g_strdup("");
+    exp_line = add_date (exp_line, trans, info);
+    exp_line = add_guid (exp_line, trans, info);
+    exp_line = add_number (exp_line, trans, info);
+    exp_line = add_description (exp_line, trans, info);
+    exp_line = add_notes (exp_line, trans, info);
+    exp_line = add_commodity (exp_line, trans, info);
+    exp_line = add_void_reason (exp_line, trans, info);
+    bool t_void = xaccTransGetVoidStatus (trans);
+
+    //Split fields
     exp_line = add_action (exp_line, split, info);
     exp_line = add_memo (exp_line, split, info);
     exp_line = add_account_name (exp_line, split, true, info);
@@ -392,32 +404,8 @@ make_split_part (gchar* exp_line, Split *split, bool t_void, CsvExportInfo *info
     exp_line = add_reconcile (exp_line, split, info);
     exp_line = add_reconcile_date (exp_line, split, info);
     exp_line = add_price (exp_line, split, t_void, info);
-    return exp_line;
-}
 
-static gchar*
-make_complex_trans_line (Transaction *trans, Split *split, CsvExportInfo *info)
-{
-    gchar *exp_line = g_strdup("");
-    exp_line = add_date (exp_line, trans, info);
-    exp_line = add_guid (exp_line, trans, info);
-    exp_line = add_number (exp_line, trans, info);
-    exp_line = add_description (exp_line, trans, info);
-    exp_line = add_notes (exp_line, trans, info);
-    exp_line = add_commodity (exp_line, trans, info);
-    exp_line = add_void_reason (exp_line, trans, info);
-    return make_split_part (exp_line, split, xaccTransGetVoidStatus (trans), info);
-}
-
-static gchar*
-make_complex_split_line (Transaction *trans, Split *split, CsvExportInfo *info)
-{
-    /* Pure split lines don't have any transaction information,
-     * so start with empty fields for all transaction columns.
-     */
-    gchar *result = g_strconcat (info->end_sep, info->mid_sep, info->mid_sep, info->mid_sep,
-            info->mid_sep, info->mid_sep, info->mid_sep, info->mid_sep, NULL);
-    return make_split_part (result, split, xaccTransGetVoidStatus (trans), info);
+    return exp_line;
 }
 
 
@@ -504,7 +492,7 @@ void account_splits (CsvExportInfo *info, Account *acc, FILE *fh )
                 continue;
 
             // Write complex Split Line.
-            line = make_complex_split_line (trans, t_split, info);
+            line = make_complex_trans_line (trans, t_split, info);
             info->failed = !write_line_to_file (fh, line);
             g_free (line);
             if (info->failed)

commit be0579dc0cde794ffef05316011c399d105d8f22
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Tue Feb 14 16:40:48 2023 +0100

    CsvTransExport - more generic code cleanup
    
    - declare variables on use
    - more concise tests and loops
    - drop unused includes
    - gboolean->bool

diff --git a/gnucash/import-export/csv-exp/assistant-csv-export.h b/gnucash/import-export/csv-exp/assistant-csv-export.h
index b0cf99cbe..9cb1f9af0 100644
--- a/gnucash/import-export/csv-exp/assistant-csv-export.h
+++ b/gnucash/import-export/csv-exp/assistant-csv-export.h
@@ -30,6 +30,7 @@
 
 #include "Account.h"
 #include "Query.h"
+#include <gtk/gtk.h>
 
 typedef enum
 {
diff --git a/gnucash/import-export/csv-exp/csv-transactions-export.c b/gnucash/import-export/csv-exp/csv-transactions-export.c
index ed8345bdd..75ea0beed 100644
--- a/gnucash/import-export/csv-exp/csv-transactions-export.c
+++ b/gnucash/import-export/csv-exp/csv-transactions-export.c
@@ -26,8 +26,6 @@
 */
 #include "config.h"
 
-#include <gtk/gtk.h>
-#include <glib/gi18n.h>
 #include <glib/gstdio.h>
 #include <stdbool.h>
 
@@ -57,23 +55,19 @@ static QofLogModule log_module = GNC_MOD_ASSISTANT;
 /*******************************************************
  * write_line_to_file
  *
- * write a text string to a file pointer, return TRUE if
+ * write a text string to a file pointer, return true if
  * successful.
  *******************************************************/
 static
-gboolean write_line_to_file (FILE *fh, char * line)
+bool write_line_to_file (FILE *fh, char * line)
 {
-    int len, written;
     DEBUG("Account String: %s", line);
 
     /* Write account line */
-    len = strlen (line);
-    written = fwrite (line, 1, len, fh);
+    int len = strlen (line);
+    int written = fwrite (line, 1, len, fh);
 
-    if (written != len)
-        return FALSE;
-    else
-        return TRUE;
+    return (written == len);
 }
 
 
@@ -85,25 +79,18 @@ gboolean write_line_to_file (FILE *fh, char * line)
 static
 gchar *csv_txn_test_field_string (CsvExportInfo *info, const gchar *string_in)
 {
-    gboolean need_quote = FALSE;
-    gchar **parts;
-    gchar *string_parts;
-    gchar *string_out;
-
     /* Check for " and then "" them */
-    parts = g_strsplit (string_in, "\"", -1);
-    string_parts = g_strjoinv ("\"\"", parts);
+    gchar **parts = g_strsplit (string_in, "\"", -1);
+    gchar *string_parts = g_strjoinv ("\"\"", parts);
     g_strfreev (parts);
 
     /* Check for separator string and \n and " in field,
        if so quote field if not already quoted */
-    if (g_strrstr (string_parts, info->separator_str) != NULL)
-        need_quote = TRUE;
-    if (g_strrstr (string_parts, "\n") != NULL)
-        need_quote = TRUE;
-    if (g_strrstr (string_parts, "\"") != NULL)
-        need_quote = TRUE;
+    bool need_quote = !g_strrstr (string_parts, info->separator_str) ||
+                      !g_strrstr (string_parts, "\n") ||
+                      !g_strrstr (string_parts, "\"");
 
+    gchar *string_out;
     if (!info->use_quotes && need_quote)
         string_out = g_strconcat ("\"", string_parts, "\"", NULL);
     else
@@ -131,11 +118,8 @@ add_date (gchar *so_far, Transaction *trans, CsvExportInfo *info)
 static gchar*
 add_guid (gchar *so_far, Transaction *trans, CsvExportInfo *info)
 {
-    gchar *result;
-    gchar *guid;
-
-    guid = guid_to_string (xaccTransGetGUID (trans));
-    result = g_strconcat (so_far, guid, info->mid_sep, NULL);
+    gchar *guid = guid_to_string (xaccTransGetGUID (trans));
+    gchar *result = g_strconcat (so_far, guid, info->mid_sep, NULL);
     g_free (guid);
     g_free (so_far);
     return result;
@@ -146,7 +130,6 @@ static gchar*
 add_reconcile_date (gchar *so_far, Split *split, CsvExportInfo *info)
 {
     gchar *result;
-
     if (xaccSplitGetReconcile (split) == YREC)
     {
         time64 t = xaccSplitGetDateReconciled (split);
@@ -164,19 +147,16 @@ add_reconcile_date (gchar *so_far, Split *split, CsvExportInfo *info)
 
 // Account Name short or Long
 static gchar*
-add_account_name (gchar *so_far, Split *split, gboolean full, CsvExportInfo *info)
+add_account_name (gchar *so_far, Split *split, bool full, CsvExportInfo *info)
 {
-    gchar       *name = NULL;
-    gchar       *conv;
-    gchar       *result;
-
-    Account     *account = xaccSplitGetAccount (split);
+    Account *account = xaccSplitGetAccount (split);
+    gchar *name = NULL;
     if (full)
         name = gnc_account_get_full_name (account);
     else
         name = g_strdup (xaccAccountGetName (account));
-    conv = csv_txn_test_field_string (info, name);
-    result = g_strconcat (so_far, conv, info->mid_sep, NULL);
+    gchar *conv = csv_txn_test_field_string (info, name);
+    gchar *result = g_strconcat (so_far, conv, info->mid_sep, NULL);
     g_free (name);
     g_free (conv);
     g_free (so_far);
@@ -187,13 +167,10 @@ add_account_name (gchar *so_far, Split *split, gboolean full, CsvExportInfo *inf
 static gchar*
 add_number (gchar *so_far, Transaction *trans, CsvExportInfo *info)
 {
-    const gchar *num;
-    gchar       *conv;
-    gchar       *result;
-
-    num = xaccTransGetNum (trans) ? xaccTransGetNum (trans) : "" ;
-    conv = csv_txn_test_field_string (info, num);
-    result = g_strconcat (so_far, conv, info->mid_sep, NULL);
+    const gchar *num = xaccTransGetNum (trans);
+    num = num ? num : "";
+    gchar *conv = csv_txn_test_field_string (info, num);
+    gchar *result = g_strconcat (so_far, conv, info->mid_sep, NULL);
     g_free (conv);
     g_free (so_far);
     return result;
@@ -203,13 +180,10 @@ add_number (gchar *so_far, Transaction *trans, CsvExportInfo *info)
 static gchar*
 add_description (gchar *so_far, Transaction *trans, CsvExportInfo *info)
 {
-    const gchar *desc;
-    gchar       *conv;
-    gchar       *result;
-
-    desc = xaccTransGetDescription (trans) ? xaccTransGetDescription (trans) : "" ;
-    conv = csv_txn_test_field_string (info, desc);
-    result = g_strconcat (so_far, conv, info->mid_sep, NULL);
+    const gchar *desc = xaccTransGetDescription (trans);
+    desc = desc ? desc : "";
+    gchar *conv = csv_txn_test_field_string (info, desc);
+    gchar *result = g_strconcat (so_far, conv, info->mid_sep, NULL);
     g_free (conv);
     g_free (so_far);
     return result;
@@ -219,13 +193,10 @@ add_description (gchar *so_far, Transaction *trans, CsvExportInfo *info)
 static gchar*
 add_notes (gchar *so_far, Transaction *trans, CsvExportInfo *info)
 {
-    const gchar *notes;
-    gchar       *conv;
-    gchar       *result;
-
-    notes = xaccTransGetNotes (trans) ? xaccTransGetNotes (trans) : "" ;
-    conv = csv_txn_test_field_string (info, notes);
-    result = g_strconcat (so_far, conv, info->mid_sep, NULL);
+    const gchar *notes = xaccTransGetNotes (trans);
+    notes = notes ? notes : "" ;
+    gchar *conv = csv_txn_test_field_string (info, notes);
+    gchar *result = g_strconcat (so_far, conv, info->mid_sep, NULL);
     g_free (conv);
     g_free (so_far);
     return result;
@@ -235,18 +206,11 @@ add_notes (gchar *so_far, Transaction *trans, CsvExportInfo *info)
 static gchar*
 add_void_reason (gchar *so_far, Transaction *trans, CsvExportInfo *info)
 {
-    gchar       *result;
-
-    if (xaccTransGetVoidStatus (trans))
-    {
-        const gchar *void_reason = xaccTransGetVoidReason (trans);
-        gchar *conv = csv_txn_test_field_string (info, void_reason);
-        result = g_strconcat (so_far, conv, info->mid_sep, NULL);
-        g_free (conv);
-    }
-    else
-        result = g_strconcat (so_far, info->mid_sep, NULL);
-
+    const gchar *void_reason = xaccTransGetVoidReason (trans);
+    void_reason = void_reason ? void_reason : "";
+    gchar *conv = csv_txn_test_field_string (info, void_reason);
+    gchar *result = g_strconcat (so_far, conv, info->mid_sep, NULL);
+    g_free (conv);
     g_free (so_far);
     return result;
 }
@@ -255,13 +219,10 @@ add_void_reason (gchar *so_far, Transaction *trans, CsvExportInfo *info)
 static gchar*
 add_memo (gchar *so_far, Split *split, CsvExportInfo *info)
 {
-    const gchar *memo;
-    gchar       *conv;
-    gchar       *result;
-
-    memo = xaccSplitGetMemo (split) ? xaccSplitGetMemo (split) : "" ;
-    conv = csv_txn_test_field_string (info, memo);
-    result = g_strconcat (so_far, conv, info->mid_sep, NULL);
+    const gchar *memo = xaccSplitGetMemo (split);
+    memo = memo ? memo : "";
+    gchar *conv = csv_txn_test_field_string (info, memo);
+    gchar *result = g_strconcat (so_far, conv, info->mid_sep, NULL);
     g_free (conv);
     g_free (so_far);
     return result;
@@ -269,19 +230,16 @@ add_memo (gchar *so_far, Split *split, CsvExportInfo *info)
 
 // Full Category Path or Not
 static gchar*
-add_category (gchar *so_far, Split *split, gboolean full, CsvExportInfo *info)
+add_category (gchar *so_far, Split *split, bool full, CsvExportInfo *info)
 {
-    gchar       *cat;
-    gchar       *conv;
-    gchar       *result;
-
+    gchar *cat;
     if (full)
         cat = xaccSplitGetCorrAccountFullName (split);
     else
         cat = g_strdup(xaccSplitGetCorrAccountName (split));
 
-    conv = csv_txn_test_field_string (info, cat);
-    result = g_strconcat (so_far, conv, info->mid_sep, NULL);
+    gchar *conv = csv_txn_test_field_string (info, cat);
+    gchar *result = g_strconcat (so_far, conv, info->mid_sep, NULL);
     g_free (cat);
     g_free (conv);
     g_free (so_far);
@@ -304,13 +262,9 @@ add_action (gchar *so_far, Split *split, CsvExportInfo *info)
 static gchar*
 add_reconcile (gchar *so_far, Split *split, CsvExportInfo *info)
 {
-    const gchar *recon;
-    gchar       *conv;
-    gchar       *result;
-
-    recon = gnc_get_reconcile_str (xaccSplitGetReconcile (split));
-    conv = csv_txn_test_field_string (info, recon);
-    result = g_strconcat (so_far, conv, info->mid_sep, NULL);
+    const gchar *recon = gnc_get_reconcile_str (xaccSplitGetReconcile (split));
+    gchar *conv = csv_txn_test_field_string (info, recon);
+    gchar *result = g_strconcat (so_far, conv, info->mid_sep, NULL);
     g_free (conv);
     g_free (so_far);
     return result;
@@ -320,14 +274,9 @@ add_reconcile (gchar *so_far, Split *split, CsvExportInfo *info)
 static gchar*
 add_commodity (gchar *so_far, Transaction *trans, CsvExportInfo *info)
 {
-    const gchar *comm_m;
-    gchar       *conv;
-    gchar       *result;
-
-    comm_m = gnc_commodity_get_unique_name (xaccTransGetCurrency (trans));
-
-    conv = csv_txn_test_field_string (info, comm_m);
-    result = g_strconcat (so_far, conv, info->mid_sep, NULL);
+    const gchar *comm_m = gnc_commodity_get_unique_name (xaccTransGetCurrency (trans));
+    gchar *conv = csv_txn_test_field_string (info, comm_m);
+    gchar *result = g_strconcat (so_far, conv, info->mid_sep, NULL);
     g_free (conv);
     g_free (so_far);
     return result;
@@ -335,18 +284,15 @@ add_commodity (gchar *so_far, Transaction *trans, CsvExportInfo *info)
 
 // Amount with Symbol or not
 static gchar*
-add_amount (gchar *so_far, Split *split, gboolean t_void, gboolean symbol, CsvExportInfo *info)
+add_amount (gchar *so_far, Split *split, bool t_void, bool symbol, CsvExportInfo *info)
 {
     const gchar *amt;
-    gchar       *conv;
-    gchar       *result;
-
     if (t_void)
         amt = xaccPrintAmount (xaccSplitVoidFormerAmount (split), gnc_split_amount_print_info (split, symbol));
     else
         amt = xaccPrintAmount (xaccSplitGetAmount (split), gnc_split_amount_print_info (split, symbol));
-    conv = csv_txn_test_field_string (info, amt);
-    result = g_strconcat (so_far, conv, info->mid_sep, NULL);
+    gchar *conv = csv_txn_test_field_string (info, amt);
+    gchar *result = g_strconcat (so_far, conv, info->mid_sep, NULL);
     g_free (conv);
     g_free (so_far);
     return result;
@@ -354,21 +300,18 @@ add_amount (gchar *so_far, Split *split, gboolean t_void, gboolean symbol, CsvEx
 
 // Value with Symbol or not
 static gchar*
-add_value (gchar *so_far, Split *split, gboolean t_void, gboolean symbol, CsvExportInfo *info)
+add_value (gchar *so_far, Split *split, bool t_void, bool symbol, CsvExportInfo *info)
 {
-    const gchar *amt;
-    gchar       *conv;
-    gchar       *result;
-
     Transaction *trans = xaccSplitGetParent(split);
     gnc_commodity *tcurr = xaccTransGetCurrency (trans);
     GNCPrintAmountInfo pai = gnc_commodity_print_info (tcurr, symbol);
+    const gchar *amt;
     if (t_void)
         amt = xaccPrintAmount (xaccSplitVoidFormerValue (split), pai);
     else
         amt = xaccPrintAmount (xaccSplitGetValue (split), pai);
-    conv = csv_txn_test_field_string (info, amt);
-    result = g_strconcat (so_far, conv, info->mid_sep, NULL);
+    gchar *conv = csv_txn_test_field_string (info, amt);
+    gchar *result = g_strconcat (so_far, conv, info->mid_sep, NULL);
     g_free (conv);
     g_free (so_far);
     return result;
@@ -376,20 +319,16 @@ add_value (gchar *so_far, Split *split, gboolean t_void, gboolean symbol, CsvExp
 
 // Share Price / Conversion factor
 static gchar*
-add_rate (gchar *so_far, Split *split, gboolean t_void, CsvExportInfo *info)
+add_rate (gchar *so_far, Split *split, bool t_void, CsvExportInfo *info)
 {
-    const gchar *amt;
     gnc_commodity *curr = xaccAccountGetCommodity (xaccSplitGetAccount (split));
-    gchar       *conv;
-    gchar       *result;
-
+    const gchar *amt;
     if (t_void)
         amt = xaccPrintAmount (gnc_numeric_zero(), gnc_default_price_print_info (curr));
     else
         amt = xaccPrintAmount (xaccSplitGetSharePrice (split), gnc_default_price_print_info (curr));
-
-    conv = csv_txn_test_field_string (info, amt);
-    result = g_strconcat (so_far, conv, info->end_sep, EOLSTR, NULL);
+    gchar *conv = csv_txn_test_field_string (info, amt);
+    gchar *result = g_strconcat (so_far, conv, info->end_sep, EOLSTR, NULL);
     g_free (conv);
     g_free (so_far);
     return result;
@@ -397,13 +336,10 @@ add_rate (gchar *so_far, Split *split, gboolean t_void, CsvExportInfo *info)
 
 // Share Price / Conversion factor
 static gchar*
-add_price (gchar *so_far, Split *split, gboolean t_void, CsvExportInfo *info)
+add_price (gchar *so_far, Split *split, bool t_void, CsvExportInfo *info)
 {
-    const gchar *string_amount;
     gnc_commodity *curr = xaccAccountGetCommodity (xaccSplitGetAccount (split));
-    gchar       *conv;
-    gchar       *result;
-
+    const gchar *string_amount;
     if (t_void)
     {
         gnc_numeric cf = gnc_numeric_div (xaccSplitVoidFormerValue (split), xaccSplitVoidFormerAmount (split), GNC_DENOM_AUTO,
@@ -413,8 +349,8 @@ add_price (gchar *so_far, Split *split, gboolean t_void, CsvExportInfo *info)
     else
         string_amount = xaccPrintAmount (xaccSplitGetSharePrice (split), gnc_default_price_print_info (curr));
 
-    conv = csv_txn_test_field_string (info, string_amount);
-    result = g_strconcat (so_far, conv, info->end_sep, EOLSTR, NULL);
+    gchar *conv = csv_txn_test_field_string (info, string_amount);
+    gchar *result = g_strconcat (so_far, conv, info->end_sep, EOLSTR, NULL);
     g_free (conv);
     g_free (so_far);
     return result;
@@ -425,34 +361,34 @@ add_price (gchar *so_far, Split *split, gboolean t_void, CsvExportInfo *info)
 static gchar*
 make_simple_trans_line (Transaction *trans, Split *split, CsvExportInfo *info)
 {
-    gboolean t_void = xaccTransGetVoidStatus (trans);
+    bool t_void = xaccTransGetVoidStatus (trans);
 
     gchar *exp_line = g_strdup("");
     exp_line = add_date (exp_line, trans, info);
-    exp_line = add_account_name (exp_line, split, TRUE, info);
+    exp_line = add_account_name (exp_line, split, true, info);
     exp_line = add_number (exp_line, trans, info);
     exp_line = add_description (exp_line, trans, info);
-    exp_line = add_category (exp_line, split, TRUE, info);
+    exp_line = add_category (exp_line, split, true, info);
     exp_line = add_reconcile (exp_line, split, info);
-    exp_line = add_amount (exp_line, split, t_void, TRUE, info);
-    exp_line = add_amount (exp_line, split, t_void, FALSE, info);
-    exp_line = add_value (exp_line, split, t_void, TRUE, info);
-    exp_line = add_value (exp_line, split, t_void, FALSE, info);
+    exp_line = add_amount (exp_line, split, t_void, true, info);
+    exp_line = add_amount (exp_line, split, t_void, false, info);
+    exp_line = add_value (exp_line, split, t_void, true, info);
+    exp_line = add_value (exp_line, split, t_void, false, info);
     exp_line = add_rate (exp_line, split, t_void, info);
     return exp_line;
 }
 
 static gchar*
-make_split_part (gchar* exp_line, Split *split, gboolean t_void, CsvExportInfo *info)
+make_split_part (gchar* exp_line, Split *split, bool t_void, CsvExportInfo *info)
 {
     exp_line = add_action (exp_line, split, info);
     exp_line = add_memo (exp_line, split, info);
-    exp_line = add_account_name (exp_line, split, TRUE, info);
-    exp_line = add_account_name (exp_line, split, FALSE, info);
-    exp_line = add_amount (exp_line, split, t_void, TRUE, info);
-    exp_line = add_amount (exp_line, split, t_void, FALSE, info);
-    exp_line = add_value (exp_line, split, t_void, TRUE, info);
-    exp_line = add_value (exp_line, split, t_void, FALSE, info);
+    exp_line = add_account_name (exp_line, split, true, info);
+    exp_line = add_account_name (exp_line, split, false, info);
+    exp_line = add_amount (exp_line, split, t_void, true, info);
+    exp_line = add_amount (exp_line, split, t_void, false, info);
+    exp_line = add_value (exp_line, split, t_void, true, info);
+    exp_line = add_value (exp_line, split, t_void, false, info);
     exp_line = add_reconcile (exp_line, split, info);
     exp_line = add_reconcile_date (exp_line, split, info);
     exp_line = add_price (exp_line, split, t_void, info);
@@ -510,7 +446,7 @@ void account_splits (CsvExportInfo *info, Account *acc, FILE *fh )
         qof_query_set_sort_order (info->query, p1, p2, NULL);
 
         xaccQueryAddSingleAccountMatch (info->query, acc, QOF_QUERY_AND);
-        xaccQueryAddDateMatchTT (info->query, TRUE, info->csvd.start_time, TRUE, info->csvd.end_time, QOF_QUERY_AND);
+        xaccQueryAddDateMatchTT (info->query, true, info->csvd.start_time, true, info->csvd.end_time, QOF_QUERY_AND);
     }
 
     /* Run the query */
@@ -589,15 +525,10 @@ void account_splits (CsvExportInfo *info, Account *acc, FILE *fh )
  *******************************************************/
 void csv_transactions_export (CsvExportInfo *info)
 {
-    FILE    *fh;
-    Account *acc;
-    GList   *ptr;
-    gboolean num_action = qof_book_use_split_action_for_num_field (gnc_get_current_book());
-
     ENTER("");
     DEBUG("File name is : %s", info->file_name);
 
-    info->failed = FALSE;
+    info->failed = false;
 
     /* Set up separators */
     if (info->use_quotes)
@@ -612,71 +543,68 @@ void csv_transactions_export (CsvExportInfo *info)
     }
 
     /* Open File for writing */
-    fh = g_fopen (info->file_name, "w" );
-    if (fh != NULL)
+    FILE *fh = g_fopen (info->file_name, "w" );
+    if (!fh)
     {
-        gchar *header;
-        int i;
+        info->failed = true;
+        return;
+    }
 
-        /* Header string */
-        if (info->simple_layout)
-        {
-            header = g_strconcat (info->end_sep,
-                         /* Translators: The following symbols will build the *
-                          * header line of exported CSV files:                */
-                                  _("Date"), info->mid_sep, _("Account Name"),
-                                  info->mid_sep, (num_action ? _("Transaction Number") : _("Number")),
-                                  info->mid_sep, _("Description"), info->mid_sep, _("Full Category Path"),
-                                  info->mid_sep, _("Reconcile"),
-                                  info->mid_sep, _("Amount With Sym"), info->mid_sep, _("Amount Num."),
-                                  info->mid_sep, _("Value With Sym"), info->mid_sep, _("Value Num."),
-                                  info->mid_sep, _("Rate/Price"),
-                                  info->end_sep, EOLSTR, NULL);
-        }
-        else
-        {
-            header = g_strconcat (info->end_sep, _("Date"), info->mid_sep, _("Transaction ID"),
-                                  info->mid_sep, (num_action ? _("Transaction Number") : _("Number")),
-                                  info->mid_sep, _("Description"), info->mid_sep, _("Notes"),
-                                  info->mid_sep, _("Commodity/Currency"), info->mid_sep, _("Void Reason"),
-                                  info->mid_sep, (num_action ? _("Number/Action") : _("Action")), info->mid_sep, _("Memo"),
-                                  info->mid_sep, _("Full Account Name"), info->mid_sep, _("Account Name"),
-                                  info->mid_sep, _("Amount With Sym"), info->mid_sep, _("Amount Num."),
-                                  info->mid_sep, _("Value With Sym"), info->mid_sep, _("Value Num."),
-                                  info->mid_sep, _("Reconcile"), info->mid_sep, _("Reconcile Date"), info->mid_sep, _("Rate/Price"),
-                                  info->end_sep, EOLSTR, NULL);
-        }
-        DEBUG("Header String: %s", header);
+    gchar *header;
+    bool num_action = qof_book_use_split_action_for_num_field (gnc_get_current_book());
+    /* Header string */
+    if (info->simple_layout)
+    {
+        header = g_strconcat (info->end_sep,
+                        /* Translators: The following symbols will build the *
+                        * header line of exported CSV files:                */
+                                _("Date"), info->mid_sep, _("Account Name"),
+                                info->mid_sep, (num_action ? _("Transaction Number") : _("Number")),
+                                info->mid_sep, _("Description"), info->mid_sep, _("Full Category Path"),
+                                info->mid_sep, _("Reconcile"),
+                                info->mid_sep, _("Amount With Sym"), info->mid_sep, _("Amount Num."),
+                                info->mid_sep, _("Value With Sym"), info->mid_sep, _("Value Num."),
+                                info->mid_sep, _("Rate/Price"),
+                                info->end_sep, EOLSTR, NULL);
+    }
+    else
+    {
+        header = g_strconcat (info->end_sep, _("Date"), info->mid_sep, _("Transaction ID"),
+                                info->mid_sep, (num_action ? _("Transaction Number") : _("Number")),
+                                info->mid_sep, _("Description"), info->mid_sep, _("Notes"),
+                                info->mid_sep, _("Commodity/Currency"), info->mid_sep, _("Void Reason"),
+                                info->mid_sep, (num_action ? _("Number/Action") : _("Action")), info->mid_sep, _("Memo"),
+                                info->mid_sep, _("Full Account Name"), info->mid_sep, _("Account Name"),
+                                info->mid_sep, _("Amount With Sym"), info->mid_sep, _("Amount Num."),
+                                info->mid_sep, _("Value With Sym"), info->mid_sep, _("Value Num."),
+                                info->mid_sep, _("Reconcile"), info->mid_sep, _("Reconcile Date"), info->mid_sep, _("Rate/Price"),
+                                info->end_sep, EOLSTR, NULL);
+    }
+    DEBUG("Header String: %s", header);
 
-        /* Write header line */
-        if (!write_line_to_file (fh, header))
-        {
-            info->failed = TRUE;
-            g_free (header);
-            return;
-        }
-        g_free (header);
+    /* Write header line */
+    info->failed = !write_line_to_file (fh, header);
+    g_free (header);
+    if (info->failed)
+        return;
 
-        if (info->export_type == XML_EXPORT_TRANS)
+    if (info->export_type == XML_EXPORT_TRANS)
+    {
+        /* Go through list of accounts */
+        for (GList *ptr = info->csva.account_list; ptr; ptr = g_list_next(ptr))
         {
-            /* Go through list of accounts */
-            for (ptr = info->csva.account_list, i = 0; ptr; ptr = g_list_next(ptr), i++)
-            {
-                acc = ptr->data;
-                DEBUG("Account being processed is : %s", xaccAccountGetName (acc));
-                account_splits (info, acc, fh);
-            }
-            g_list_free (info->csva.account_list);
+            Account *acc = ptr->data;
+            DEBUG("Account being processed is : %s", xaccAccountGetName (acc));
+            account_splits (info, acc, fh);
         }
-        else
-            account_splits (info, info->account, fh);
-
-        g_list_free (info->trans_list); // free trans_list
+        g_list_free (info->csva.account_list);
     }
     else
-        info->failed = TRUE;
-    if (fh)
-        fclose (fh);
+        account_splits (info, info->account, fh);
+
+    g_list_free (info->trans_list); // free trans_list
+
+    fclose (fh);
     LEAVE("");
 }
 

commit 9df059e9a5f60d0cf99a937940e88977c7b0e4c8
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Tue Feb 14 14:52:59 2023 +0100

    CsvTransExport - omit trading splits unless exporting from a trading account

diff --git a/gnucash/import-export/csv-exp/csv-transactions-export.c b/gnucash/import-export/csv-exp/csv-transactions-export.c
index 13d7b5a07..ed8345bdd 100644
--- a/gnucash/import-export/csv-exp/csv-transactions-export.c
+++ b/gnucash/import-export/csv-exp/csv-transactions-export.c
@@ -494,6 +494,7 @@ make_complex_split_line (Transaction *trans, Split *split, CsvExportInfo *info)
 static
 void account_splits (CsvExportInfo *info, Account *acc, FILE *fh )
 {
+    bool is_trading_acct = acc && (xaccAccountGetType (acc) == ACCT_TYPE_TRADING);
 
     // Setup the query for normal transaction export
     if (info->export_type == XML_EXPORT_TRANS)
@@ -527,6 +528,11 @@ void account_splits (CsvExportInfo *info, Account *acc, FILE *fh )
         if (!split_acc)
             continue;
 
+        // Only export trading splits when exporting a trading account
+        if (!is_trading_acct &&
+            (xaccAccountGetType (split_acc) == ACCT_TYPE_TRADING))
+            continue;
+
         if (info->simple_layout)
         {
             // Write line in simple layout, equivalent to a single line register view
@@ -555,6 +561,11 @@ void account_splits (CsvExportInfo *info, Account *acc, FILE *fh )
             if (split == t_split)
                 continue;
 
+            // Only export trading splits if exporting a trading account
+            Account *tsplit_acc = xaccSplitGetAccount (t_split);
+            if (!is_trading_acct &&
+                (xaccAccountGetType (tsplit_acc) == ACCT_TYPE_TRADING))
+                continue;
 
             // Write complex Split Line.
             line = make_complex_split_line (trans, t_split, info);

commit c6a93903b3495a124e7d8515fb7effb34db79fa8
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Tue Feb 14 12:45:56 2023 +0100

    CsvTransExport - generic code cleanup
    
    - declare variables on use
    - more concise tests and loops

diff --git a/gnucash/import-export/csv-exp/csv-transactions-export.c b/gnucash/import-export/csv-exp/csv-transactions-export.c
index ab177ab7e..13d7b5a07 100644
--- a/gnucash/import-export/csv-exp/csv-transactions-export.c
+++ b/gnucash/import-export/csv-exp/csv-transactions-export.c
@@ -29,6 +29,7 @@
 #include <gtk/gtk.h>
 #include <glib/gi18n.h>
 #include <glib/gstdio.h>
+#include <stdbool.h>
 
 #include "gnc-commodity.h"
 #include "gnc-ui-util.h"
@@ -422,7 +423,7 @@ add_price (gchar *so_far, Split *split, gboolean t_void, CsvExportInfo *info)
 /******************************************************************************/
 
 static gchar*
-make_simple_trans_line (Account *acc, Transaction *trans, Split *split, CsvExportInfo *info)
+make_simple_trans_line (Transaction *trans, Split *split, CsvExportInfo *info)
 {
     gboolean t_void = xaccTransGetVoidStatus (trans);
 
@@ -459,7 +460,7 @@ make_split_part (gchar* exp_line, Split *split, gboolean t_void, CsvExportInfo *
 }
 
 static gchar*
-make_complex_trans_line (Account *acc, Transaction *trans, Split *split, CsvExportInfo *info)
+make_complex_trans_line (Transaction *trans, Split *split, CsvExportInfo *info)
 {
     gchar *exp_line = g_strdup("");
     exp_line = add_date (exp_line, trans, info);
@@ -493,21 +494,18 @@ make_complex_split_line (Transaction *trans, Split *split, CsvExportInfo *info)
 static
 void account_splits (CsvExportInfo *info, Account *acc, FILE *fh )
 {
-    GSList  *p1, *p2;
-    GList   *splits;
-    QofBook *book;
 
     // Setup the query for normal transaction export
     if (info->export_type == XML_EXPORT_TRANS)
     {
         info->query = qof_query_create_for (GNC_ID_SPLIT);
-        book = gnc_get_current_book();
+        QofBook *book = gnc_get_current_book();
         qof_query_set_book (info->query, book);
 
         /* Sort by transaction date */
-        p1 = g_slist_prepend (NULL, TRANS_DATE_POSTED);
+        GSList *p1 = g_slist_prepend (NULL, TRANS_DATE_POSTED);
         p1 = g_slist_prepend (p1, SPLIT_TRANS);
-        p2 = g_slist_prepend (NULL, QUERY_DEFAULT_SORT);
+        GSList *p2 = g_slist_prepend (NULL, QUERY_DEFAULT_SORT);
         qof_query_set_sort_order (info->query, p1, p2, NULL);
 
         xaccQueryAddSingleAccountMatch (info->query, acc, QOF_QUERY_AND);
@@ -515,83 +513,61 @@ void account_splits (CsvExportInfo *info, Account *acc, FILE *fh )
     }
 
     /* Run the query */
-    for (splits = qof_query_run (info->query); splits; splits = splits->next)
+    for (GList *splits = qof_query_run (info->query); splits; splits = splits->next)
     {
-        Split       *split;
-        Transaction *trans;
-        SplitList   *s_list;
-        GList       *node;
-        Split       *t_split;
-        int          nSplits;
-        int          cnt;
-        gchar       *line;
-
-        split = splits->data;
-        trans = xaccSplitGetParent (split);
-        nSplits = xaccTransCountSplits (trans);
-        s_list = xaccTransGetSplitList (trans);
+        Split *split = splits->data;
 
         // Look for trans already exported in trans_list
-        if (g_list_find (info->trans_list, trans) != NULL)
+        Transaction *trans = xaccSplitGetParent (split);
+        if (g_list_find (info->trans_list, trans))
             continue;
 
         // Look for blank split
-        if (xaccSplitGetAccount (split) == NULL)
+        Account *split_acc = xaccSplitGetAccount (split);
+        if (!split_acc)
             continue;
 
-        // This will be a simple layout equivalent to a single line register view.
         if (info->simple_layout)
         {
-            line = make_simple_trans_line (acc, trans, split, info);
-
-            /* Write to file */
-            if (!write_line_to_file (fh, line))
-            {
-                info->failed = TRUE;
-                break;
-            }
+            // Write line in simple layout, equivalent to a single line register view
+            gchar *line = make_simple_trans_line (trans, split, info);
+            info->failed = !write_line_to_file (fh, line);
             g_free (line);
+            if (info->failed)
+                break;
+
             continue;
         }
 
-        // Complex Transaction Line.
-        line = make_complex_trans_line (acc, trans, split, info);
-
-        /* Write to file */
-        if (!write_line_to_file (fh, line))
-        {
-            info->failed = TRUE;
-            break;
-        }
+        // Write complex Transaction Line.
+        gchar *line = make_complex_trans_line (trans, split, info);
+        info->failed = !write_line_to_file (fh, line);
         g_free (line);
+        if (info->failed)
+            break;
 
         /* Loop through the list of splits for the Transaction */
-        node = s_list;
-        cnt = 0;
-        while ((cnt < nSplits) && (info->failed == FALSE))
+        for (GList *node = xaccTransGetSplitList (trans); node; node = node->next)
         {
-            t_split = node->data;
+            Split *t_split = node->data;
 
             // base split is already written on the trans_line
-            if (split != t_split)
-            {
-            // Complex Split Line.
-                line = make_complex_split_line (trans, t_split, info);
+            if (split == t_split)
+                continue;
 
-                if (!write_line_to_file (fh, line))
-                    info->failed = TRUE;
 
-                g_free (line);
-            }
-
-            cnt++;
-            node = node->next;
+            // Write complex Split Line.
+            line = make_complex_split_line (trans, t_split, info);
+            info->failed = !write_line_to_file (fh, line);
+            g_free (line);
+            if (info->failed)
+                break;
         }
         info->trans_list = g_list_prepend (info->trans_list, trans); // add trans to trans_list
     }
+
     if (info->export_type == XML_EXPORT_TRANS)
         qof_query_destroy (info->query);
-    g_list_free (splits);
 }
 
 

commit 003f379d88785af7cb181ac197bf058d52641b45
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Tue Feb 14 11:43:46 2023 +0100

    Bug 798600 - CSV import of multi-split security transactions fails to load capital gain - part 2
    
    Update csv transaction export format to include split values.
    In the csv importer the 'GnuCash Export Format' option will
    now include values. For compatibility with filex exported
    from older gnucash versions the previous preset is still
    available under the name 'GnuCash Export Format (4.x and older)'.

diff --git a/gnucash/import-export/csv-exp/csv-transactions-export.c b/gnucash/import-export/csv-exp/csv-transactions-export.c
index f709dc443..ab177ab7e 100644
--- a/gnucash/import-export/csv-exp/csv-transactions-export.c
+++ b/gnucash/import-export/csv-exp/csv-transactions-export.c
@@ -351,6 +351,28 @@ add_amount (gchar *so_far, Split *split, gboolean t_void, gboolean symbol, CsvEx
     return result;
 }
 
+// Value with Symbol or not
+static gchar*
+add_value (gchar *so_far, Split *split, gboolean t_void, gboolean symbol, CsvExportInfo *info)
+{
+    const gchar *amt;
+    gchar       *conv;
+    gchar       *result;
+
+    Transaction *trans = xaccSplitGetParent(split);
+    gnc_commodity *tcurr = xaccTransGetCurrency (trans);
+    GNCPrintAmountInfo pai = gnc_commodity_print_info (tcurr, symbol);
+    if (t_void)
+        amt = xaccPrintAmount (xaccSplitVoidFormerValue (split), pai);
+    else
+        amt = xaccPrintAmount (xaccSplitGetValue (split), pai);
+    conv = csv_txn_test_field_string (info, amt);
+    result = g_strconcat (so_far, conv, info->mid_sep, NULL);
+    g_free (conv);
+    g_free (so_far);
+    return result;
+}
+
 // Share Price / Conversion factor
 static gchar*
 add_rate (gchar *so_far, Split *split, gboolean t_void, CsvExportInfo *info)
@@ -413,6 +435,8 @@ make_simple_trans_line (Account *acc, Transaction *trans, Split *split, CsvExpor
     exp_line = add_reconcile (exp_line, split, info);
     exp_line = add_amount (exp_line, split, t_void, TRUE, info);
     exp_line = add_amount (exp_line, split, t_void, FALSE, info);
+    exp_line = add_value (exp_line, split, t_void, TRUE, info);
+    exp_line = add_value (exp_line, split, t_void, FALSE, info);
     exp_line = add_rate (exp_line, split, t_void, info);
     return exp_line;
 }
@@ -426,6 +450,8 @@ make_split_part (gchar* exp_line, Split *split, gboolean t_void, CsvExportInfo *
     exp_line = add_account_name (exp_line, split, FALSE, info);
     exp_line = add_amount (exp_line, split, t_void, TRUE, info);
     exp_line = add_amount (exp_line, split, t_void, FALSE, info);
+    exp_line = add_value (exp_line, split, t_void, TRUE, info);
+    exp_line = add_value (exp_line, split, t_void, FALSE, info);
     exp_line = add_reconcile (exp_line, split, info);
     exp_line = add_reconcile_date (exp_line, split, info);
     exp_line = add_price (exp_line, split, t_void, info);
@@ -614,8 +640,10 @@ void csv_transactions_export (CsvExportInfo *info)
                                   _("Date"), info->mid_sep, _("Account Name"),
                                   info->mid_sep, (num_action ? _("Transaction Number") : _("Number")),
                                   info->mid_sep, _("Description"), info->mid_sep, _("Full Category Path"),
-                                  info->mid_sep, _("Reconcile"), info->mid_sep, _("Amount With Sym"),
-                                  info->mid_sep, _("Amount Num."), info->mid_sep, _("Rate/Price"),
+                                  info->mid_sep, _("Reconcile"),
+                                  info->mid_sep, _("Amount With Sym"), info->mid_sep, _("Amount Num."),
+                                  info->mid_sep, _("Value With Sym"), info->mid_sep, _("Value Num."),
+                                  info->mid_sep, _("Rate/Price"),
                                   info->end_sep, EOLSTR, NULL);
         }
         else
@@ -627,6 +655,7 @@ void csv_transactions_export (CsvExportInfo *info)
                                   info->mid_sep, (num_action ? _("Number/Action") : _("Action")), info->mid_sep, _("Memo"),
                                   info->mid_sep, _("Full Account Name"), info->mid_sep, _("Account Name"),
                                   info->mid_sep, _("Amount With Sym"), info->mid_sep, _("Amount Num."),
+                                  info->mid_sep, _("Value With Sym"), info->mid_sep, _("Value Num."),
                                   info->mid_sep, _("Reconcile"), info->mid_sep, _("Reconcile Date"), info->mid_sep, _("Rate/Price"),
                                   info->end_sep, EOLSTR, NULL);
         }
diff --git a/gnucash/import-export/csv-imp/gnc-imp-settings-csv-tx.cpp b/gnucash/import-export/csv-imp/gnc-imp-settings-csv-tx.cpp
index a2e503704..151ce9116 100644
--- a/gnucash/import-export/csv-imp/gnc-imp-settings-csv-tx.cpp
+++ b/gnucash/import-export/csv-imp/gnc-imp-settings-csv-tx.cpp
@@ -90,6 +90,8 @@ static std::shared_ptr<CsvTransImpSettings> create_int_gnc_exp_preset(void)
             GncTransPropType::NONE,
             GncTransPropType::NONE,
             GncTransPropType::AMOUNT,
+            GncTransPropType::NONE,
+            GncTransPropType::VALUE,
             GncTransPropType::REC_STATE,
             GncTransPropType::REC_DATE,
             GncTransPropType::PRICE
@@ -97,6 +99,40 @@ static std::shared_ptr<CsvTransImpSettings> create_int_gnc_exp_preset(void)
     return preset;
 }
 
+static std::shared_ptr<CsvTransImpSettings> create_int_gnc_exp_4_preset(void)
+{
+    auto preset = std::make_shared<CsvTransImpSettings>();
+    preset->m_name = get_gnc_exp_4();
+    preset->m_skip_start_lines = 1;
+    preset->m_multi_split = true;
+
+    /* FIXME date and currency format should still be aligned with export format!
+     * That's currently hard to do, because the export uses whatever the user
+     * had set as global preference.
+     *   preset->date_active = 0;
+     *   preset->currency_active = 0;
+     */
+    preset->m_column_types = {
+        GncTransPropType::DATE,
+        GncTransPropType::UNIQUE_ID,
+        GncTransPropType::NUM,
+        GncTransPropType::DESCRIPTION,
+        GncTransPropType::NOTES,
+        GncTransPropType::COMMODITY,
+        GncTransPropType::VOID_REASON,
+        GncTransPropType::ACTION,
+        GncTransPropType::MEMO,
+        GncTransPropType::ACCOUNT,
+        GncTransPropType::NONE,
+        GncTransPropType::NONE,
+        GncTransPropType::AMOUNT,
+        GncTransPropType::REC_STATE,
+        GncTransPropType::REC_DATE,
+        GncTransPropType::PRICE
+    };
+    return preset;
+}
+
 /**************************************************
  * find
  *
@@ -134,6 +170,7 @@ const preset_vec_trans& get_import_presets_trans (void)
     /* Start with the internally generated ones */
     presets_trans.push_back(create_int_no_preset());
     presets_trans.push_back(create_int_gnc_exp_preset());
+    presets_trans.push_back(create_int_gnc_exp_4_preset());
 
     /* Then add all the ones we found in the state file */
     for (auto preset_name : preset_names)
diff --git a/gnucash/import-export/csv-imp/gnc-imp-settings-csv.cpp b/gnucash/import-export/csv-imp/gnc-imp-settings-csv.cpp
index 7bd8e4432..ae5e6f396 100644
--- a/gnucash/import-export/csv-imp/gnc-imp-settings-csv.cpp
+++ b/gnucash/import-export/csv-imp/gnc-imp-settings-csv.cpp
@@ -45,6 +45,7 @@
 const std::string csv_group_prefix{"CSV-"};
 const std::string no_settings{N_("No Settings")};
 const std::string gnc_exp{N_("GnuCash Export Format")};
+const std::string gnc_exp_4{N_("GnuCash Export Format (4.x and older)")};
 
 #define CSV_NAME         "Name"
 #define CSV_FORMAT       "CsvFormat"
@@ -107,6 +108,11 @@ std::string get_gnc_exp (void)
     return gnc_exp;
 }
 
+std::string get_gnc_exp_4 (void)
+{
+    return gnc_exp_4;
+}
+
 /**************************************************
  * load_common
  *
diff --git a/gnucash/import-export/csv-imp/gnc-imp-settings-csv.hpp b/gnucash/import-export/csv-imp/gnc-imp-settings-csv.hpp
index bb344ce39..92a277ba8 100644
--- a/gnucash/import-export/csv-imp/gnc-imp-settings-csv.hpp
+++ b/gnucash/import-export/csv-imp/gnc-imp-settings-csv.hpp
@@ -90,6 +90,7 @@ protected:
 
 std::string get_no_settings (void);
 std::string get_gnc_exp (void);
+std::string get_gnc_exp_4 (void);
 
 /** Check whether name can be used as a preset name.
  *  The names of the internal presets are considered reserved.

commit 9e1268d9347f9375865a5f52becb9d52f23eb3ad
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Tue Feb 14 10:40:42 2023 +0100

    Bug 798600 - CSV import of multi-split security transactions fails to load capital gain - part 1
    
    Transactions with capital gains processing can have
    splits in transaction currency with a zero amount
    and a non-zero value. To properly import those,
    prefer the value column even if transaction
    currency equals account commodity.
    Previous (wrong) assumption was that in case
    of a same-currency split, the amount would
    always be the value.

diff --git a/gnucash/import-export/csv-imp/gnc-imp-props-tx.cpp b/gnucash/import-export/csv-imp/gnc-imp-props-tx.cpp
index 3c1496bcd..354d2b6c8 100644
--- a/gnucash/import-export/csv-imp/gnc-imp-props-tx.cpp
+++ b/gnucash/import-export/csv-imp/gnc-imp-props-tx.cpp
@@ -758,15 +758,15 @@ void GncPreSplit::create_split (std::shared_ptr<DraftTransaction> draft_trans)
     auto value = GncNumeric();
     auto trans_curr = xaccTransGetCurrency(draft_trans->trans);
     auto acct_comm = xaccAccountGetCommodity(account);
-    if (gnc_commodity_equiv(trans_curr, acct_comm))
-        value = amount;
-    else if (m_value || m_value_neg)
+    if (m_value || m_value_neg)
     {
         if (m_value)
             value += *m_value;
         if (m_value_neg)
             value -= *m_value_neg;
     }
+    else if (gnc_commodity_equiv(trans_curr, acct_comm))
+            value = amount;
     else if (tamount)
         value = -*tamount;
     else if (m_price)



Summary of changes:
 .../import-export/csv-exp/assistant-csv-export.c   |  69 ++-
 .../import-export/csv-exp/assistant-csv-export.h   |   4 +-
 .../csv-exp/csv-transactions-export.c              | 480 +++++++++------------
 gnucash/import-export/csv-imp/gnc-imp-props-tx.cpp |   6 +-
 .../csv-imp/gnc-imp-settings-csv-tx.cpp            |  37 ++
 .../import-export/csv-imp/gnc-imp-settings-csv.cpp |   6 +
 .../import-export/csv-imp/gnc-imp-settings-csv.hpp |   1 +
 7 files changed, 284 insertions(+), 319 deletions(-)



More information about the gnucash-changes mailing list