gnucash stable: Multiple changes pushed

Geert Janssens gjanssens at code.gnucash.org
Thu May 16 13:56:09 EDT 2024


Updated	 via  https://github.com/Gnucash/gnucash/commit/03622b03 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/3101eed3 (commit)
	 via  https://github.com/Gnucash/gnucash/commit/e175e53a (commit)
	from  https://github.com/Gnucash/gnucash/commit/31095c12 (commit)



commit 03622b03d0e93f65f411c287d02f11d7e101e623
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Thu May 16 17:46:32 2024 +0200

    CsvImp - refactor of GncTxImport::set_column_type and helper functions
    
    ...to improve readability.

diff --git a/gnucash/import-export/csv-imp/gnc-import-tx.cpp b/gnucash/import-export/csv-imp/gnc-import-tx.cpp
index 0c6b59e50c..8db28ce325 100644
--- a/gnucash/import-export/csv-imp/gnc-import-tx.cpp
+++ b/gnucash/import-export/csv-imp/gnc-import-tx.cpp
@@ -748,20 +748,50 @@ GncTxImport::check_for_column_type (GncTransPropType type)
                         != m_settings.m_column_types.end());
 }
 
-/* A helper function intended to be called only from set_column_type */
-void GncTxImport::update_pre_trans_split_props (uint32_t row, uint32_t col, GncTransPropType old_type, GncTransPropType new_type)
+
+void GncTxImport::update_pre_split_multi_col_prop (parse_line_t& parsed_line, GncTransPropType col_type)
+{
+    if (!is_multi_col_prop(col_type))
+        return;
+
+    auto input_vec = std::get<PL_INPUT>(parsed_line);
+    auto split_props = std::get<PL_PRESPLIT> (parsed_line);
+
+    /* All amount columns may appear more than once. The net amount
+        * needs to be recalculated rather than just reset if one column
+        * is unset. */
+    for (auto col_it = m_settings.m_column_types.cbegin();
+            col_it < m_settings.m_column_types.cend();
+            col_it++)
+            if (*col_it == col_type)
+            {
+                auto value = std::string();
+                auto col_num = static_cast<uint32_t>(col_it - m_settings.m_column_types.cbegin());
+
+                if (col_num < input_vec.size())
+                    value = input_vec.at(col_num);
+                split_props->add (col_type, value);
+            }
+}
+
+void GncTxImport::update_pre_trans_props (parse_line_t& parsed_line, uint32_t col, GncTransPropType old_type, GncTransPropType new_type)
 {
-    /* Deal with trans properties first as this may change the trans->split relationships
-     * in case of multi-split imports */
-    auto trans_props = std::get<PL_PRETRANS> (m_parsed_lines[row]);
+    auto input_vec = std::get<PL_INPUT>(parsed_line);
+    auto trans_props = std::get<PL_PRETRANS> (parsed_line);
+
+    /* Reset date and currency formats for each trans/split props object
+     * to ensure column updates use the most recent one */
+    trans_props->set_date_format (m_settings.m_date_format);
+    trans_props->set_multi_split (m_settings.m_multi_split);
+
     if ((old_type > GncTransPropType::NONE) && (old_type <= GncTransPropType::TRANS_PROPS))
         trans_props->reset (old_type);
     if ((new_type > GncTransPropType::NONE) && (new_type <= GncTransPropType::TRANS_PROPS))
     {
         auto value = std::string();
 
-        if (col < std::get<PL_INPUT>(m_parsed_lines[row]).size())
-            value = std::get<PL_INPUT>(m_parsed_lines[row]).at(col);
+        if (col < input_vec.size())
+            value = input_vec.at(col);
 
         trans_props->set(new_type, value);
     }
@@ -772,18 +802,22 @@ void GncTxImport::update_pre_trans_split_props (uint32_t row, uint32_t col, GncT
      * counters should be reset. */
     if ((old_type == GncTransPropType::ACCOUNT) || (new_type == GncTransPropType::ACCOUNT))
         trans_props->reset_cross_split_counters();
+}
 
-    /* All transaction related value updates are finished now,
-     * time to determine what to do with the updated GncPreTrans copy.
-     *
-     * For multi-split input data this line may be part of a transaction
-     * that has already been started by a previous line. In that case
-     * reuse the GncPreTrans from that previous line (which we track
-     * in m_parent).
-     * In all other cases our new GncPreTrans should be used for this line
-     * and be marked as the new potential m_parent for subsequent lines.
+void GncTxImport::update_pre_split_props (parse_line_t& parsed_line, uint32_t col, GncTransPropType old_type, GncTransPropType new_type)
+{
+    /* With multi-split input data this line may be part of a transaction
+     * that has already been started by a previous parsed line.
+     * If so
+     * - set the GncPreTrans from that previous line (which we track
+     * in m_parent) as this GncPreSplit's pre_trans.
+     * In all other cases
+     * - set the GncPreTrans that's unique to this line
+     * as this GncPreSplit's pre_trans
+     * - mark it as the new potential m_parent for subsequent lines.
      */
-    auto split_props = std::get<PL_PRESPLIT> (m_parsed_lines[row]);
+    auto split_props = std::get<PL_PRESPLIT> (parsed_line);
+    auto trans_props = std::get<PL_PRETRANS> (parsed_line);
     if (m_settings.m_multi_split && trans_props->is_part_of( m_parent))
         split_props->set_pre_trans (m_parent);
     else
@@ -792,61 +826,35 @@ void GncTxImport::update_pre_trans_split_props (uint32_t row, uint32_t col, GncT
         m_parent = trans_props;
     }
 
-    /* Finally handle any split related property changes */
     if ((old_type > GncTransPropType::TRANS_PROPS) && (old_type <= GncTransPropType::SPLIT_PROPS))
     {
         split_props->reset (old_type);
         if (is_multi_col_prop(old_type))
-        {
-
-            /* All amount columns may appear more than once. The net amount
-            * needs to be recalculated rather than just reset if one column
-            * is unset. */
-            for (auto col_it = m_settings.m_column_types.cbegin();
-                    col_it < m_settings.m_column_types.cend();
-                    col_it++)
-                if (*col_it == old_type)
-                {
-                    auto value = std::string();
-                    auto col_num = static_cast<uint32_t>(col_it - m_settings.m_column_types.cbegin());
-
-                    if (col_num < std::get<PL_INPUT>(m_parsed_lines[row]).size())
-                        value = std::get<PL_INPUT>(m_parsed_lines[row]).at(col_num);
-                    split_props->add (old_type, value);
-                }
-        }
+            update_pre_split_multi_col_prop (parsed_line, old_type);
     }
+
     if ((new_type > GncTransPropType::TRANS_PROPS) && (new_type <= GncTransPropType::SPLIT_PROPS))
     {
-        /* All amount columns may appear more than once. The net amount
-            * needs to be recalculated rather than just reset if one column
-            * is set. */
         if (is_multi_col_prop(new_type))
         {
             split_props->reset(new_type);
-            /* For Deposits and Withdrawal we have to sum all columns with this property */
-            for (auto col_it = m_settings.m_column_types.cbegin();
-                    col_it < m_settings.m_column_types.cend();
-                    col_it++)
-                if (*col_it == new_type)
-                {
-                    auto value = std::string();
-                    auto col_num = static_cast<uint32_t>(col_it - m_settings.m_column_types.cbegin());
-
-                    if (col_num < std::get<PL_INPUT>(m_parsed_lines[row]).size())
-                        value = std::get<PL_INPUT>(m_parsed_lines[row]).at(col_num);
-                    split_props->add (new_type, value);
-                }
+            update_pre_split_multi_col_prop (parsed_line, new_type);
         }
         else
         {
+            auto input_vec = std::get<PL_INPUT>(parsed_line);
             auto value = std::string();
-            if (col < std::get<PL_INPUT>(m_parsed_lines[row]).size())
-                value = std::get<PL_INPUT>(m_parsed_lines[row]).at(col);
+            if (col < input_vec.size())
+                value = input_vec.at(col);
             split_props->set(new_type, value);
         }
     }
     m_multi_currency |= split_props->get_pre_trans()->is_multi_currency();
+
+    /* Collect errors from this line's GncPreSplit and its embedded GncPreTrans */
+    auto all_errors = split_props->get_pre_trans()->errors();
+    all_errors.merge (split_props->errors());
+    std::get<PL_ERROR>(parsed_line) = std::move(all_errors);
 }
 
 
@@ -875,28 +883,10 @@ GncTxImport::set_column_type (uint32_t position, GncTransPropType type, bool for
     /* Update the preparsed data */
     m_parent = nullptr;
     m_multi_currency = false;
-    for (auto parsed_lines_it = m_parsed_lines.begin();
-            parsed_lines_it != m_parsed_lines.end();
-            ++parsed_lines_it)
+    for (auto& parsed_lines_it: m_parsed_lines)
     {
-        /* Reset date and currency formats for each trans/split props object
-         * to ensure column updates use the most recent one
-         */
-        auto split_props = std::get<PL_PRESPLIT>(*parsed_lines_it);
-        split_props->get_pre_trans()->set_date_format (m_settings.m_date_format);
-        split_props->get_pre_trans()->set_multi_split (m_settings.m_multi_split);
-        split_props->set_date_format (m_settings.m_date_format);
-        split_props->set_currency_format (m_settings.m_currency_format);
-
-        uint32_t row = parsed_lines_it - m_parsed_lines.begin();
-
-        /* Update the property represented by the new column type */
-        update_pre_trans_split_props (row, position, old_type, type);
-
-        /* Report errors if there are any */
-        auto all_errors = split_props->get_pre_trans()->errors();
-        all_errors.merge (split_props->errors());
-        std::get<PL_ERROR>(*parsed_lines_it) = std::move(all_errors);
+        update_pre_trans_props (parsed_lines_it, position, old_type, type);
+        update_pre_split_props (parsed_lines_it, position, old_type, type);
     }
 }
 
diff --git a/gnucash/import-export/csv-imp/gnc-import-tx.hpp b/gnucash/import-export/csv-imp/gnc-import-tx.hpp
index 5e1a792d6d..f2bb4e2765 100644
--- a/gnucash/import-export/csv-imp/gnc-import-tx.hpp
+++ b/gnucash/import-export/csv-imp/gnc-import-tx.hpp
@@ -182,10 +182,12 @@ private:
      */
     std::shared_ptr<DraftTransaction> trans_properties_to_trans (std::vector<parse_line_t>::iterator& parsed_line);
 
-    /* Internal helper function that should only be called from within
+    /* Internal helper functions that should only be called from within
      * set_column_type for consistency (otherwise error messages may not be (re)set)
      */
-    void update_pre_trans_split_props (uint32_t row, uint32_t col, GncTransPropType old_type, GncTransPropType new_type);
+    void update_pre_split_multi_col_prop (parse_line_t& parsed_line, GncTransPropType col_type);
+    void update_pre_trans_props (parse_line_t& parsed_line, uint32_t col, GncTransPropType old_type, GncTransPropType new_type);
+    void update_pre_split_props (parse_line_t& parsed_line, uint32_t col, GncTransPropType old_type, GncTransPropType new_type);
 
     CsvTransImpSettings m_settings;
     bool m_skip_errors;

commit 3101eed3c09c9ae7fc13c168c9a32b92bb175871
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Thu May 16 17:45:11 2024 +0200

    Bug 799309 - Import Multi-split CSV can duplictae 'Notes' field from one transaction to next

diff --git a/gnucash/import-export/csv-imp/gnc-import-tx.cpp b/gnucash/import-export/csv-imp/gnc-import-tx.cpp
index a73239d656..0c6b59e50c 100644
--- a/gnucash/import-export/csv-imp/gnc-import-tx.cpp
+++ b/gnucash/import-export/csv-imp/gnc-import-tx.cpp
@@ -411,7 +411,7 @@ void GncTxImport::tokenize (bool guessColTypes)
             auto presplit = std::make_shared<GncPreSplit>(date_format(), currency_format());
             presplit->set_pre_trans (std::move (pretrans));
             m_parsed_lines.push_back (std::make_tuple (tokenized_line, ErrMap(),
-                                      std::move (presplit), false));
+                                      presplit->get_pre_trans(), std::move (presplit), false));
         }
         if (length > max_cols)
             max_cols = length;
@@ -606,7 +606,7 @@ std::shared_ptr<DraftTransaction> GncTxImport::trans_properties_to_trans (std::v
 {
     auto created_trans = false;
     std::shared_ptr<GncPreSplit> split_props;
-    std::tie(std::ignore, std::ignore, split_props, std::ignore) = *parsed_line;
+    std::tie(std::ignore, std::ignore, std::ignore, split_props, std::ignore) = *parsed_line;
     auto trans_props = split_props->get_pre_trans();
     auto account = split_props->get_account();
 
@@ -655,11 +655,10 @@ std::shared_ptr<DraftTransaction> GncTxImport::trans_properties_to_trans (std::v
 
 void GncTxImport::create_transaction (std::vector<parse_line_t>::iterator& parsed_line)
 {
-    StrVec line;
     ErrMap errors;
     std::shared_ptr<GncPreSplit> split_props = nullptr;
     bool skip_line = false;
-    std::tie(line, errors, split_props, skip_line) = *parsed_line;
+    std::tie(std::ignore, errors, std::ignore, split_props, skip_line) = *parsed_line;
     auto trans_props = split_props->get_pre_trans();
 
     if (skip_line)
@@ -752,15 +751,9 @@ GncTxImport::check_for_column_type (GncTransPropType type)
 /* A helper function intended to be called only from set_column_type */
 void GncTxImport::update_pre_trans_split_props (uint32_t row, uint32_t col, GncTransPropType old_type, GncTransPropType new_type)
 {
-    /* Deliberately make a copy of the GncPreTrans. It may be the original one was shared
-     * with a previous line and should no longer be after the transprop is changed.
-     * This doesn't apply for the GncPreSplit so we just get a pointer to it for easier processing.
-     */
-    auto split_props = std::get<PL_PRESPLIT>(m_parsed_lines[row]);
-    auto trans_props = std::make_shared<GncPreTrans> (*(split_props->get_pre_trans()).get());
-
     /* Deal with trans properties first as this may change the trans->split relationships
-        * in case of multi-split imports */
+     * in case of multi-split imports */
+    auto trans_props = std::get<PL_PRETRANS> (m_parsed_lines[row]);
     if ((old_type > GncTransPropType::NONE) && (old_type <= GncTransPropType::TRANS_PROPS))
         trans_props->reset (old_type);
     if ((new_type > GncTransPropType::NONE) && (new_type <= GncTransPropType::TRANS_PROPS))
@@ -790,6 +783,7 @@ void GncTxImport::update_pre_trans_split_props (uint32_t row, uint32_t col, GncT
      * In all other cases our new GncPreTrans should be used for this line
      * and be marked as the new potential m_parent for subsequent lines.
      */
+    auto split_props = std::get<PL_PRESPLIT> (m_parsed_lines[row]);
     if (m_settings.m_multi_split && trans_props->is_part_of( m_parent))
         split_props->set_pre_trans (m_parent);
     else
diff --git a/gnucash/import-export/csv-imp/gnc-import-tx.hpp b/gnucash/import-export/csv-imp/gnc-import-tx.hpp
index aee84ae15a..5e1a792d6d 100644
--- a/gnucash/import-export/csv-imp/gnc-import-tx.hpp
+++ b/gnucash/import-export/csv-imp/gnc-import-tx.hpp
@@ -52,12 +52,15 @@ extern const gchar* currency_format_user[];
 /** An enum describing the columns found in a parse_line_t. Currently these are:
  *  - a tokenized line of input
  *  - an optional error string
- *  - a struct to hold user selected properties for a transaction
+ *  - a struct to hold user selected properties for a transaction as found on the current line
  *  - a struct to hold user selected properties for one or two splits in the above transaction
+ *    this split struct also contains a trans props struct like above, but the included one
+ *    may be shared by several split lines that comprise a single transaction
  *  - a boolean to mark the line as skipped by error and/or user or not */
 enum parse_line_cols {
     PL_INPUT,
     PL_ERROR,
+    PL_PRETRANS,
     PL_PRESPLIT,
     PL_SKIP
 };
@@ -69,6 +72,7 @@ using StrVec = std::vector<std::string>;
  * with std::get to access the columns. */
 using parse_line_t = std::tuple<StrVec,
                                 ErrMap,
+                                std::shared_ptr<GncPreTrans>,
                                 std::shared_ptr<GncPreSplit>,
                                 bool>;
 

commit e175e53aacb3a0b5e9c8bf58b67dd8d772da8645
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Thu May 16 16:25:47 2024 +0200

    CsvImp - fix error message displayed to user (and related comment)

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 9589c93381..49ab27ab35 100644
--- a/gnucash/import-export/csv-imp/gnc-imp-props-tx.cpp
+++ b/gnucash/import-export/csv-imp/gnc-imp-props-tx.cpp
@@ -647,8 +647,8 @@ StrVec GncPreSplit::verify_essentials()
         err_msg.emplace_back (_("Transfer split is reconciled but transfer reconcile date column is missing or invalid."));
 
 
-    /* In multisplit mode and where current account selections imply multi-
-     * currency transactions, we require extra columns to ensure each split is
+    /* When current account selections imply multi-currency
+     * transactions, we require extra columns to ensure each split is
      * fully defined.
      * Note this check only involves splits created by the csv importer
      * code. The generic import matcher may add a balancing split
@@ -662,7 +662,7 @@ StrVec GncPreSplit::verify_essentials()
             err_msg.emplace_back( _("Choice of accounts makes this a multi-currency transaction but price or (negated) value column is missing or invalid."));
         else if (!m_pre_trans->m_multi_split &&
             !m_price && !m_value && !m_value_neg && !m_tamount && !m_tamount_neg )
-            err_msg.emplace_back( _("Choice of account makes this a multi-currency transaction but price, (negated) value or (negated) transfer column is missing or invalid."));
+            err_msg.emplace_back( _("Choice of accounts makes this a multi-currency transaction but price, (negated) value or (negated) transfer amount column is missing or invalid."));
     }
 
     return err_msg;



Summary of changes:
 gnucash/import-export/csv-imp/gnc-imp-props-tx.cpp |   6 +-
 gnucash/import-export/csv-imp/gnc-import-tx.cpp    | 150 +++++++++------------
 gnucash/import-export/csv-imp/gnc-import-tx.hpp    |  12 +-
 3 files changed, 79 insertions(+), 89 deletions(-)



More information about the gnucash-changes mailing list