1 /********************************************************************\ 2 * gnc-import-price.hpp - import prices from csv files * 3 * * 4 * This program is free software; you can redistribute it and/or * 5 * modify it under the terms of the GNU General Public License as * 6 * published by the Free Software Foundation; either version 2 of * 7 * the License, or (at your option) any later version. * 8 * * 9 * This program is distributed in the hope that it will be useful, * 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 12 * GNU General Public License for more details. * 13 * * 14 * You should have received a copy of the GNU General Public License* 15 * along with this program; if not, contact: * 16 * * 17 * Free Software Foundation Voice: +1-617-542-5942 * 18 * 51 Franklin Street, Fifth Floor Fax: +1-617-542-2652 * 19 * Boston, MA 02110-1301, USA gnu@gnu.org * 20 \********************************************************************/ 21 22 /** @file 23 @brief Class to import prices from CSV or fixed width files 24 * 25 gnc-import-price.hpp 26 @author Copyright (c) 2015 Geert Janssens <geert@kobaltwit.be> 27 @author Copyright (c) 2017 Robert Fewell 28 */ 29 30 #ifndef GNC_PRICE_IMPORT_HPP 31 #define GNC_PRICE_IMPORT_HPP 32 33 extern "C" { 34 #include "config.h" 35 #include "gnc-commodity.h" 36 } 37 38 #include <vector> 39 #include <set> 40 #include <map> 41 #include <memory> 42 43 #include "gnc-tokenizer.hpp" 44 #include "gnc-imp-props-price.hpp" 45 #include "gnc-imp-settings-csv-price.hpp" 46 #include <boost/optional.hpp> 47 48 /* A set of currency formats that the user sees. */ 49 extern const int num_currency_formats_price; 50 extern const gchar* currency_format_user_price[]; 51 52 /** An enum describing the columns found in a parse_line_t. Currently these are: 53 * - a tokenized line of input 54 * - an optional error string 55 * - a struct to hold user selected properties for a price 56 * - a boolean to mark the line as skipped by error and/or user or not */ 57 enum parse_line_cols { 58 PL_INPUT, 59 PL_ERROR, 60 PL_PREPRICE, 61 PL_SKIP 62 }; 63 64 /** Tuple to hold 65 * - a tokenized line of input 66 * - an optional error string 67 * - a struct to hold user selected properties for a price */ 68 using parse_line_t = std::tuple<StrVec, 69 std::string, 70 std::shared_ptr<GncImportPrice>, 71 bool>; 72 struct ErrorListPrice; 73 74 /** The actual PriceImport class 75 * It's intended to use in the following sequence of actions: 76 * - set a file format 77 * - load a file 78 * - optionally convert it's encoding 79 * - parse the file into lines, which in turn are split up in to columns 80 * the result of this step can be queried from tokenizer 81 * - the user should now map the columns to types, which is stored in column_types 82 * - last step is convert the mapped columns into a list of prices to add */ 83 class GncPriceImport 84 { 85 public: 86 // Constructor - Destructor 87 GncPriceImport(GncImpFileFormat format = GncImpFileFormat::UNKNOWN); 88 ~GncPriceImport(); 89 90 void file_format(GncImpFileFormat format); 91 GncImpFileFormat file_format(); 92 93 void over_write (bool over); 94 bool over_write (); 95 96 void from_commodity (gnc_commodity *from_commodity); 97 gnc_commodity *from_commodity (); 98 99 void to_currency (gnc_commodity *to_currency); 100 gnc_commodity *to_currency (); 101 102 void currency_format (int currency_format); 103 int currency_format (); 104 105 void date_format (int date_format); 106 int date_format (); 107 108 void encoding (const std::string& encoding); 109 std::string encoding (); 110 111 void update_skipped_lines (boost::optional<uint32_t> start, boost::optional<uint32_t> end, 112 boost::optional<bool> alt, boost::optional<bool> errors); 113 uint32_t skip_start_lines (); 114 uint32_t skip_end_lines (); 115 bool skip_alt_lines (); 116 bool skip_err_lines (); 117 118 void separators (std::string separators); 119 std::string separators (); 120 121 void settings (const CsvPriceImpSettings& settings); 122 bool save_settings (); 123 124 void settings_name (std::string name); 125 std::string settings_name (); 126 127 128 void load_file (const std::string& filename); 129 130 void tokenize (bool guessColTypes); 131 132 std::string verify(); 133 134 /** This function will attempt to convert all tokenized lines into 135 * prices using the column types the user has set. 136 */ 137 void create_prices (); 138 bool check_for_column_type (GncPricePropType type); 139 void set_column_type_price (uint32_t position, GncPricePropType type, bool force = false); 140 std::vector<GncPricePropType> column_types_price (); 141 142 std::unique_ptr<GncTokenizer> m_tokenizer; /**< Will handle file loading/encoding conversion/splitting into fields */ 143 std::vector<parse_line_t> m_parsed_lines; /**< source file parsed into a two-dimensional array of strings. 144 Per line also holds possible error messages and objects with extracted 145 price properties. */ 146 int m_prices_added; 147 int m_prices_duplicated; 148 int m_prices_replaced; 149 150 private: 151 /** A helper function used by create_prices. It will attempt 152 * to convert a single tokenized line into a price using 153 * the column types the user has set. 154 */ 155 void create_price (std::vector<parse_line_t>::iterator& parsed_line); 156 157 void verify_column_selections (ErrorListPrice& error_msg); 158 159 /* Internal helper function to force reparsing of columns subject to format changes */ 160 void reset_formatted_column (std::vector<GncPricePropType>& col_types); 161 162 /* Two internal helper functions that should only be called from within 163 * set_column_type_price for consistency (otherwise error messages may not be (re)set) 164 */ 165 void update_price_props (uint32_t row, uint32_t col, GncPricePropType prop_type); 166 167 CsvPriceImpSettings m_settings; 168 bool m_skip_errors; 169 bool m_over_write; 170 }; 171 172 173 #endif 174