gnucash maint: 797171 - Allow multiple credit/debit columns to be selected

Geert Janssens gjanssens at code.gnucash.org
Fri Sep 6 10:55:29 EDT 2019


Updated	 via  https://github.com/Gnucash/gnucash/commit/25cc3307 (commit)
	from  https://github.com/Gnucash/gnucash/commit/bbcf19ae (commit)



commit 25cc3307228d7ec6f216767f628bf241ae720d1d
Author: Geert Janssens <geert at kobaltwit.be>
Date:   Wed Aug 28 20:55:29 2019 +0200

    797171 - Allow multiple credit/debit columns to be selected
    
    This required some tweaks in the core csv import code
    - first don't unset other deposit/withdrawal columns when selecting a second one
    - amounts have to be summed for all deposit/withdrawal colums
      I have added a new member function 'add' in addition to 'set' and 'reset'
      That function will only work for deposit or withdrawal columns

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 c1e358695..e196d1a7d 100644
--- a/gnucash/import-export/csv-imp/gnc-imp-props-tx.cpp
+++ b/gnucash/import-export/csv-imp/gnc-imp-props-tx.cpp
@@ -502,6 +502,55 @@ void GncPreSplit::reset (GncTransPropType prop_type)
     }
 }
 
+void GncPreSplit::add (GncTransPropType prop_type, const std::string& value)
+{
+    try
+    {
+        // Drop any existing error for the prop_type we're about to add to
+        m_errors.erase(prop_type);
+
+        Account *acct = nullptr;
+        auto num_val = GncNumeric();
+        switch (prop_type)
+        {
+            case GncTransPropType::DEPOSIT:
+                num_val = parse_amount (value, m_currency_format); // Will throw if parsing fails
+                if (m_deposit)
+                    num_val += *m_deposit;
+                m_deposit = num_val;
+                break;
+
+            case GncTransPropType::WITHDRAWAL:
+                num_val = parse_amount (value, m_currency_format); // Will throw if parsing fails
+                if (m_withdrawal)
+                    num_val += *m_withdrawal;
+                m_withdrawal = num_val;
+                break;
+
+            default:
+                /* Issue a warning for all other prop_types. */
+                PWARN ("%d can't be used to add values in a split", static_cast<int>(prop_type));
+                break;
+        }
+    }
+    catch (const std::invalid_argument& e)
+    {
+        auto err_str = std::string(_(gnc_csv_col_type_strs[prop_type])) +
+        std::string(_(" could not be understood.\n")) +
+        e.what();
+        m_errors.emplace(prop_type, err_str);
+        throw std::invalid_argument (err_str);
+    }
+    catch (const std::out_of_range& e)
+    {
+        auto err_str = std::string(_(gnc_csv_col_type_strs[prop_type])) +
+        std::string(_(" could not be understood.\n")) +
+        e.what();
+        m_errors.emplace(prop_type, err_str);
+        throw std::invalid_argument (err_str);
+    }
+}
+
 std::string GncPreSplit::verify_essentials (void)
 {
     auto err_msg = std::string();
diff --git a/gnucash/import-export/csv-imp/gnc-imp-props-tx.hpp b/gnucash/import-export/csv-imp/gnc-imp-props-tx.hpp
index ee0052926..b8936961f 100644
--- a/gnucash/import-export/csv-imp/gnc-imp-props-tx.hpp
+++ b/gnucash/import-export/csv-imp/gnc-imp-props-tx.hpp
@@ -157,6 +157,7 @@ public:
         m_currency_format{currency_format}{};
     void set (GncTransPropType prop_type, const std::string& value);
     void reset (GncTransPropType prop_type);
+    void add (GncTransPropType prop_type, const std::string& value);
     void set_date_format (int date_format) { m_date_format = date_format ;}
     void set_currency_format (int currency_format) { m_currency_format = currency_format; }
     std::string verify_essentials (void);
diff --git a/gnucash/import-export/csv-imp/gnc-import-tx.cpp b/gnucash/import-export/csv-imp/gnc-import-tx.cpp
index 99536136b..df76f014b 100644
--- a/gnucash/import-export/csv-imp/gnc-import-tx.cpp
+++ b/gnucash/import-export/csv-imp/gnc-import-tx.cpp
@@ -792,24 +792,41 @@ void GncTxImport::update_pre_split_props (uint32_t row, uint32_t col, GncTransPr
 
     auto split_props = std::get<PL_PRESPLIT>(m_parsed_lines[row]);
 
-    if (col == std::get<PL_INPUT>(m_parsed_lines[row]).size())
-        split_props->reset (prop_type);
-    else
+    split_props->reset (prop_type);
+    try
     {
-        try
+        // Except for Deposit or Withdrawal lines there can only be
+        // one column with a given property type.
+        if ((prop_type != GncTransPropType::DEPOSIT) &&
+            (prop_type != GncTransPropType::WITHDRAWAL))
         {
             auto value = std::get<PL_INPUT>(m_parsed_lines[row]).at(col);
             split_props->set(prop_type, value);
         }
-        catch (const std::exception& e)
+        else
         {
-            /* Do nothing, just prevent the exception from escalating up
-             * However log the error if it happens on a row that's not skipped
-             */
-            if (!std::get<PL_SKIP>(m_parsed_lines[row]))
-                PINFO("User warning: %s", e.what());
+            // 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 == prop_type)
+                {
+                    auto col_num = col_it - m_settings.m_column_types.cbegin();
+                    auto value = std::get<PL_INPUT>(m_parsed_lines[row]).at(col_num);
+                    split_props->add (prop_type, value);
+                }
+            }
         }
     }
+    catch (const std::exception& e)
+    {
+        /* Do nothing, just prevent the exception from escalating up
+            * However log the error if it happens on a row that's not skipped
+            */
+        if (!std::get<PL_SKIP>(m_parsed_lines[row]))
+            PINFO("User warning: %s", e.what());
+    }
 }
 
 
@@ -823,8 +840,11 @@ GncTxImport::set_column_type (uint32_t position, GncTransPropType type, bool for
     if ((type == old_type) && !force)
         return; /* Nothing to do */
 
-    // Column types should be unique, so remove any previous occurrence of the new type
-    std::replace(m_settings.m_column_types.begin(), m_settings.m_column_types.end(),
+    // Column types except deposit and withdrawal should be unique,
+    // so remove any previous occurrence of the new type
+    if ((type != GncTransPropType::DEPOSIT) &&
+        (type != GncTransPropType::WITHDRAWAL))
+        std::replace(m_settings.m_column_types.begin(), m_settings.m_column_types.end(),
             type, GncTransPropType::NONE);
 
     m_settings.m_column_types.at (position) = type;



Summary of changes:
 gnucash/import-export/csv-imp/gnc-imp-props-tx.cpp | 49 ++++++++++++++++++++++
 gnucash/import-export/csv-imp/gnc-imp-props-tx.hpp |  1 +
 gnucash/import-export/csv-imp/gnc-import-tx.cpp    | 44 +++++++++++++------
 3 files changed, 82 insertions(+), 12 deletions(-)



More information about the gnucash-changes mailing list