ORE Studio 0.0.4
Loading...
Searching...
No Matches
OreImportWizard.hpp
1/* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2 *
3 * Copyright (C) 2026 Marco Craveiro <marco.craveiro@gmail.com>
4 *
5 * This program is free software; you can redistribute it and/or modify it under
6 * the terms of the GNU General Public License as published by the Free Software
7 * Foundation; either version 3 of the License, or (at your option) any later
8 * version.
9 *
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
13 * details.
14 *
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc., 51
17 * Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 *
19 */
20#ifndef ORES_QT_ORE_IMPORT_WIZARD_HPP
21#define ORES_QT_ORE_IMPORT_WIZARD_HPP
22
23#include <map>
24#include <optional>
25#include <string>
26#include <boost/uuid/uuid.hpp>
27#include <QWizard>
28#include <QWizardPage>
29#include <QLabel>
30#include <QLineEdit>
31#include <QPushButton>
32#include <QProgressBar>
33#include <QTextEdit>
34#include <QRadioButton>
35#include <QCheckBox>
36#include <QListWidget>
37#include <QTreeWidget>
38#include <QComboBox>
39#include <QDateEdit>
40#include <filesystem>
41#include <vector>
42#include "ores.logging/make_logger.hpp"
43#include "ores.qt/ClientManager.hpp"
44#include "ores.ore/scanner/scan_result.hpp"
45#include "ores.ore/planner/import_choices.hpp"
46#include "ores.ore/planner/ore_import_plan.hpp"
47#include "ores.refdata.api/domain/book.hpp"
48#include "ores.ore.api/messaging/ore_import_protocol.hpp"
49
50namespace ores::qt {
51
64class OreImportWizard final : public QWizard {
65 Q_OBJECT
66
67private:
68 inline static std::string_view logger_name = "ores.qt.ore_import_wizard";
69
70 [[nodiscard]] static auto& lg() {
71 using namespace ores::logging;
72 static auto instance = make_logger(logger_name);
73 return instance;
74 }
75
76public:
77 enum PageId {
78 Page_Welcome = 0,
79 Page_Directory,
80 Page_ScanSummary,
81 Page_Currency,
82 Page_Portfolio,
83 Page_TradeImport,
84 Page_Done
85 };
86
87 explicit OreImportWizard(ClientManager* clientManager,
88 std::optional<boost::uuids::uuid> targetBookId = std::nullopt,
89 const std::string& targetBookName = "",
90 QWidget* parent = nullptr);
91
92 const std::string& targetBookName() const { return targetBookName_; }
93 ~OreImportWizard() override = default;
94
95 ClientManager* clientManager() const { return clientManager_; }
96
97 // Shared state — written by pages, read by subsequent pages
98 ore::scanner::scan_result& scanResult() { return scanResult_; }
99 ore::planner::import_choices& choices() { return choices_; }
100 ore::planner::ore_import_plan& importPlan() { return importPlan_; }
101
102 void setScanResult(ore::scanner::scan_result r) { scanResult_ = std::move(r); }
103
104 // ORE directory picked on Page_Directory — needed by Page_TradeImport for upload
105 void setOreDir(std::filesystem::path dir) { ore_dir_ = std::move(dir); }
106 const std::filesystem::path& oreDir() const { return ore_dir_; }
107
108 // HTTP base URL set by OreImportController before the wizard is shown
109 void setHttpBaseUrl(std::string url) { http_base_url_ = std::move(url); }
110 const std::string& httpBaseUrl() const { return http_base_url_; }
111
112 // Results set by Page_TradeImport after the server-side import completes
113 void setImportResponse(ores::ore::messaging::ore_import_response response) {
114 import_response_ = std::move(response);
115 importSuccess_ = import_response_.success;
116 importError_ = QString::fromStdString(import_response_.message);
117 }
118 bool importSuccess() const { return importSuccess_; }
119 QString importError() const { return importError_; }
120 const ores::ore::messaging::ore_import_response& importResponse() const {
121 return import_response_;
122 }
123
124 // Existing ISO codes fetched on Page_Currency
125 const std::set<std::string>& existingIsoCodes() const { return existingIsoCodes_; }
126 void setExistingIsoCodes(std::set<std::string> codes) {
127 existingIsoCodes_ = std::move(codes);
128 }
129
130 // Existing portfolio names fetched on Page_Portfolio
131 const std::vector<std::string>& existingPortfolioNames() const {
132 return existingPortfolioNames_;
133 }
134 void setExistingPortfolioNames(std::vector<std::string> names) {
135 existingPortfolioNames_ = std::move(names);
136 }
137
138private:
139 void setupPages();
140
141 ClientManager* clientManager_;
142 std::string targetBookName_;
143 ore::scanner::scan_result scanResult_;
146 std::set<std::string> existingIsoCodes_;
147 std::vector<std::string> existingPortfolioNames_;
148
149 std::filesystem::path ore_dir_;
150 std::string http_base_url_;
152 bool importSuccess_ = false;
153 QString importError_;
154};
155
156// ============================================================================
157// Page declarations
158// ============================================================================
159
160class OreWelcomePage final : public QWizardPage {
161 Q_OBJECT
162public:
163 explicit OreWelcomePage(OreImportWizard* wizard);
164private:
165 OreImportWizard* wizard_;
166};
167
168class OreDirectoryPage final : public QWizardPage {
169 Q_OBJECT
170
171private:
172 inline static std::string_view logger_name = "ores.qt.ore_directory_page";
173 [[nodiscard]] static auto& lg() {
174 using namespace ores::logging;
175 static auto instance = make_logger(logger_name);
176 return instance;
177 }
178
179public:
180 explicit OreDirectoryPage(OreImportWizard* wizard);
181 bool isComplete() const override;
182 bool validatePage() override;
183
184private slots:
185 void onBrowseClicked();
186 void onScanFinished();
187
188private:
189 void startScan();
190
191 OreImportWizard* wizard_;
192 QLineEdit* dirEdit_;
193 QPushButton* browseBtn_;
194 QLabel* statusLabel_;
195 QProgressBar* progressBar_;
196 bool scanComplete_ = false;
197 bool scanning_ = false;
198};
199
200class OreScanSummaryPage final : public QWizardPage {
201 Q_OBJECT
202public:
203 explicit OreScanSummaryPage(OreImportWizard* wizard);
204 void initializePage() override;
205
206private slots:
207 void onExclusionAdded();
208 void onExclusionRemoved();
209
210private:
211 void refreshSummary();
212
213 OreImportWizard* wizard_;
214 QLabel* summaryLabel_;
215 QListWidget* exclusionList_;
216 QLineEdit* exclusionEdit_;
217 QPushButton* addBtn_;
218 QPushButton* removeBtn_;
219 QLabel* hierarchyLabel_;
220};
221
222class OreCurrencyPage final : public QWizardPage {
223 Q_OBJECT
224
225private:
226 inline static std::string_view logger_name = "ores.qt.ore_currency_page";
227 [[nodiscard]] static auto& lg() {
228 using namespace ores::logging;
229 static auto instance = make_logger(logger_name);
230 return instance;
231 }
232
233public:
234 explicit OreCurrencyPage(OreImportWizard* wizard);
235 void initializePage() override;
236
237private slots:
238 void onFetchFinished();
239 void onModeChanged();
240
241private:
242 OreImportWizard* wizard_;
243 QRadioButton* allRadio_;
244 QRadioButton* missingRadio_;
245 QLabel* statusLabel_;
246 QLabel* countLabel_;
247 bool fetchDone_ = false;
248};
249
250class OrePortfolioPage final : public QWizardPage {
251 Q_OBJECT
252
253private:
254 inline static std::string_view logger_name = "ores.qt.ore_portfolio_page";
255 [[nodiscard]] static auto& lg() {
256 using namespace ores::logging;
257 static auto instance = make_logger(logger_name);
258 return instance;
259 }
260
261public:
262 explicit OrePortfolioPage(OreImportWizard* wizard);
263 void initializePage() override;
264 bool isComplete() const override;
265 bool validatePage() override;
266
267private slots:
268 void onBookSelectionChanged();
269 void onBooksFetchFinished();
270
271private:
272 OreImportWizard* wizard_;
273 QComboBox* parentCombo_;
274 QLabel* hierarchyPreviewLabel_;
275 bool fetchDone_ = false;
276 // name → book domain object for existing books fetched from server
277 std::map<std::string, refdata::domain::book> booksByName_;
278};
279
280class OreTradeImportPage final : public QWizardPage {
281 Q_OBJECT
282
283private:
284 inline static std::string_view logger_name = "ores.qt.ore_trade_import_page";
285 [[nodiscard]] static auto& lg() {
286 using namespace ores::logging;
287 static auto instance = make_logger(logger_name);
288 return instance;
289 }
290
291public:
292 explicit OreTradeImportPage(OreImportWizard* wizard);
293 void initializePage() override;
294 bool isComplete() const override;
295 bool validatePage() override;
296
297private slots:
298 void onActivityTypesFetchFinished();
299 void onCounterpartiesFetchFinished();
300 void onImportFinished();
301
302private:
303 void startImport();
304 void appendLog(const QString& msg);
305
306 OreImportWizard* wizard_;
307 QLineEdit* tradeDateEdit_;
308 QComboBox* lifecycleEventCombo_;
309 QComboBox* defaultCounterpartyCombo_;
310 QLabel* counterpartyStatusLabel_;
311 QLabel* statusLabel_;
312 QProgressBar* progressBar_;
313 QTextEdit* logOutput_;
314 bool importDone_ = false;
315 bool importStarted_ = false;
316};
317
318class OreDonePage final : public QWizardPage {
319 Q_OBJECT
320public:
321 explicit OreDonePage(OreImportWizard* wizard);
322 void initializePage() override;
323private:
324 void setupIdRow(QWidget* container, QLabel* label, QLineEdit* edit,
325 QPushButton* copyBtn, const QString& labelText);
326
327 OreImportWizard* wizard_;
328 QLabel* summaryLabel_;
329
330 // Selectable ID rows — shown only when the IDs are present
331 QWidget* workflowIdRow_ = nullptr;
332 QLineEdit* workflowIdEdit_ = nullptr;
333 QWidget* correlIdRow_ = nullptr;
334 QLineEdit* correlIdEdit_ = nullptr;
335};
336
337}
338
339#endif
Implements logging infrastructure for ORE Studio.
Definition boost_severity.hpp:28
Qt-based graphical user interface for ORE Studio.
Definition AccountController.hpp:32
Response for an ore_import_request.
Definition ore_import_protocol.hpp:64
User-supplied choices that drive the import plan.
Definition import_choices.hpp:69
Complete, ready-to-execute import plan produced by ore_import_planner.
Definition ore_import_plan.hpp:37
Result of scanning an ORE directory for importable files.
Definition scan_result.hpp:31
Manages the lifecycle of the NATS client and login state.
Definition ClientManager.hpp:123
7-page wizard for importing ORE directory data into OreStudio.
Definition OreImportWizard.hpp:64