mirror of
https://github.com/feather-wallet/feather.git
synced 2025-04-16 18:01:54 +00:00
history: rework csv export
This commit is contained in:
parent
4bcd397aad
commit
055b898c85
6 changed files with 526 additions and 83 deletions
|
@ -13,6 +13,7 @@
|
|||
#include "dialog/AddressCheckerIndexDialog.h"
|
||||
#include "dialog/BalanceDialog.h"
|
||||
#include "dialog/DebugInfoDialog.h"
|
||||
#include "dialog/HistoryExportDialog.h"
|
||||
#include "dialog/PasswordDialog.h"
|
||||
#include "dialog/TxBroadcastDialog.h"
|
||||
#include "dialog/TxConfAdvDialog.h"
|
||||
|
@ -1714,26 +1715,8 @@ void MainWindow::onTxPoolBacklog(const QVector<quint64> &backlog, quint64 origin
|
|||
}
|
||||
|
||||
void MainWindow::onExportHistoryCSV() {
|
||||
QString filePath = QFileDialog::getSaveFileName(this, "Save CSV file", QDir::homePath(), "CSV (*.csv)");
|
||||
if (filePath.isEmpty())
|
||||
return;
|
||||
if (!filePath.endsWith(".csv"))
|
||||
filePath += ".csv";
|
||||
QFileInfo fileInfo(filePath);
|
||||
QDir dir = fileInfo.absoluteDir();
|
||||
|
||||
if (!dir.exists()) {
|
||||
Utils::showError(this, "Unable to export transaction history", QString("Path does not exist: %1").arg(dir.absolutePath()));
|
||||
return;
|
||||
}
|
||||
|
||||
bool success = m_wallet->history()->writeCSV(filePath);
|
||||
if (!success) {
|
||||
Utils::showError(this, "Unable to export transaction history", QString("No permission to write to: %1").arg(filePath));
|
||||
return;
|
||||
}
|
||||
|
||||
Utils::showInfo(this, "CSV export", QString("Transaction history exported to %1").arg(filePath));
|
||||
HistoryExportDialog dialog{m_wallet, this};
|
||||
dialog.exec();
|
||||
}
|
||||
|
||||
void MainWindow::onImportHistoryDescriptionsCSV() {
|
||||
|
|
190
src/dialog/HistoryExportDialog.cpp
Normal file
190
src/dialog/HistoryExportDialog.cpp
Normal file
|
@ -0,0 +1,190 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: The Monero Project
|
||||
|
||||
#include "HistoryExportDialog.h"
|
||||
#include "ui_HistoryExportDialog.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
|
||||
#include "Utils.h"
|
||||
#include "WalletManager.h"
|
||||
#include "libwalletqt/Wallet.h"
|
||||
#include "TransactionHistory.h"
|
||||
#include "utils/AppData.h"
|
||||
|
||||
HistoryExportDialog::HistoryExportDialog(Wallet *wallet, QWidget *parent)
|
||||
: WindowModalDialog(parent)
|
||||
, ui(new Ui::HistoryExportDialog)
|
||||
, m_wallet(wallet)
|
||||
{
|
||||
ui->setupUi(this);
|
||||
|
||||
connect(ui->btn_export, &QPushButton::clicked, this, &HistoryExportDialog::exportHistory);
|
||||
|
||||
connect(ui->radio_everything, &QRadioButton::toggled, [this](bool toggled) {
|
||||
if (!toggled) return;
|
||||
this->setEverything();
|
||||
});
|
||||
|
||||
connect(ui->radio_YTD, &QRadioButton::toggled, [this](bool toggled) {
|
||||
if (!toggled) return;
|
||||
ui->date_min->setDate(QDate(QDate::currentDate().year(), 1, 1));
|
||||
ui->date_max->setDate(QDate::currentDate());
|
||||
});
|
||||
|
||||
connect(ui->radio_lastDays, &QRadioButton::toggled, [this](bool toggled) {
|
||||
ui->spin_days->setEnabled(toggled);
|
||||
if (!toggled) return;
|
||||
ui->date_min->setDate(QDate::currentDate().addDays(-ui->spin_days->value() + 1));
|
||||
ui->date_max->setDate(QDate::currentDate());
|
||||
});
|
||||
|
||||
connect(ui->spin_days, &QSpinBox::valueChanged, [this] {
|
||||
ui->date_min->setDate(QDate::currentDate().addDays(-ui->spin_days->value() + 1));
|
||||
ui->date_max->setDate(QDate::currentDate());
|
||||
});
|
||||
|
||||
connect(ui->radio_lastMonth, &QRadioButton::toggled, [this](bool toggled) {
|
||||
if (!toggled) return;
|
||||
ui->date_min->setDate(QDate(QDate::currentDate().year(), QDate::currentDate().month(), 1).addMonths(-1));
|
||||
ui->date_max->setDate(QDate(QDate::currentDate().year(), QDate::currentDate().month(), 1).addDays(-1));
|
||||
});
|
||||
|
||||
connect(ui->radio_lastYear, &QRadioButton::toggled, [this](bool toggled) {
|
||||
if (!toggled) return;
|
||||
ui->date_min->setDate(QDate(QDate::currentDate().year() - 1, 1, 1));
|
||||
ui->date_max->setDate(QDate(QDate::currentDate().year(), 1, 1).addDays(-1));
|
||||
});
|
||||
|
||||
connect(ui->radio_customRange, &QRadioButton::toggled, [this](bool toggled) {
|
||||
ui->date_min->setEnabled(toggled);
|
||||
ui->date_max->setEnabled(toggled);
|
||||
});
|
||||
|
||||
this->setEverything();
|
||||
|
||||
this->adjustSize();
|
||||
}
|
||||
|
||||
void HistoryExportDialog::setEverything()
|
||||
{
|
||||
ui->date_min->setDate(QDate(2014,4,18));
|
||||
ui->date_max->setDate(QDate::currentDate());
|
||||
}
|
||||
|
||||
void HistoryExportDialog::exportHistory()
|
||||
{
|
||||
QString wallet_name = m_wallet->walletName();
|
||||
QString csv_file_name = QString("/history_export_%1.csv").arg(wallet_name);
|
||||
|
||||
QString filePath = QFileDialog::getSaveFileName(this, "Save CSV file", QDir::homePath() + csv_file_name, "CSV (*.csv)");
|
||||
if (filePath.isEmpty())
|
||||
return;
|
||||
if (!filePath.endsWith(".csv"))
|
||||
filePath += ".csv";
|
||||
QFileInfo fileInfo(filePath);
|
||||
QDir dir = fileInfo.absoluteDir();
|
||||
|
||||
if (!dir.exists()) {
|
||||
Utils::showError(this, "Unable to export transaction history", QString("Path does not exist: %1").arg(dir.absolutePath()));
|
||||
return;
|
||||
}
|
||||
|
||||
auto num_transactions = m_wallet->history()->count();
|
||||
|
||||
QList<QPair<uint64_t, QString>> csvData;
|
||||
|
||||
for (int i = 0; i < num_transactions; i++) {
|
||||
TransactionRow* tx = m_wallet->history()->transaction(i);
|
||||
|
||||
QDate minimumDate = ui->date_min->date();
|
||||
if (tx->timestamp().date() < minimumDate) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QDate maximumDate = ui->date_max->date();
|
||||
if (tx->timestamp().date() > maximumDate) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ui->check_excludePending->isChecked() && tx->isPending()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ui->check_excludeFailed->isChecked() && tx->isFailed()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ui->radio_incomingTransactions->isChecked() && tx->direction() != TransactionRow::Direction_In) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ui->radio_outgoingTransactions->isChecked() && tx->direction() != TransactionRow::Direction_Out) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ui->radio_coinbaseTransactions->isChecked() && !tx->isCoinbase()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
QString date = QString("%1T%2Z").arg(tx->date(), tx->time());
|
||||
|
||||
QString direction = QString("");
|
||||
if (tx->direction() == TransactionRow::Direction_In)
|
||||
direction = QString("in");
|
||||
else if (tx->direction() == TransactionRow::Direction_Out)
|
||||
direction = QString("out");
|
||||
else
|
||||
continue; // skip TransactionInfo::Direction_Both
|
||||
|
||||
QString balanceDelta = WalletManager::displayAmount(abs(tx->balanceDelta()));
|
||||
if (tx->direction() == TransactionRow::Direction_Out) {
|
||||
balanceDelta = "-" + balanceDelta;
|
||||
}
|
||||
|
||||
QString paymentId = tx->paymentId();
|
||||
if (paymentId == "0000000000000000") {
|
||||
paymentId = "";
|
||||
}
|
||||
|
||||
const double usd_price = appData()->txFiatHistory->get(tx->timestamp().toString("yyyyMMdd"));
|
||||
double fiat_price = usd_price * tx->amount();
|
||||
QString fiatAmount = (usd_price > 0) ? QString::number(fiat_price, 'f', 2) : "?";
|
||||
|
||||
QString line = QString(R"(%1,%2,"%3",%4,"%5",%6,%7,%8,"%9","%10","%11","%12","%13")")
|
||||
.arg(QString::number(tx->blockHeight()),
|
||||
QString::number(tx->timestamp().toSecsSinceEpoch()),
|
||||
date,
|
||||
QString::number(tx->subaddrAccount()),
|
||||
direction,
|
||||
balanceDelta,
|
||||
tx->displayAmount(),
|
||||
tx->fee(),
|
||||
tx->hash(),
|
||||
tx->description(),
|
||||
paymentId,
|
||||
fiatAmount,
|
||||
"USD");
|
||||
csvData.append({tx->blockHeight(), line});
|
||||
}
|
||||
|
||||
std::sort(csvData.begin(), csvData.end(), [](const QPair<uint64_t, QString> &tx1, const QPair<uint64_t, QString> &tx2){
|
||||
return tx1.first < tx2.first;
|
||||
});
|
||||
|
||||
QString csvString = "blockHeight,timestamp,date,accountIndex,direction,balanceDelta,amount,fee,txid,description,paymentId,fiatAmount,fiatCurrency";
|
||||
for (const auto& data : csvData) {
|
||||
csvString += "\n" + data.second;
|
||||
}
|
||||
|
||||
bool success = Utils::fileWrite(filePath, csvString);
|
||||
|
||||
if (!success) {
|
||||
Utils::showError(this, "Unable to export transaction history", QString("No permission to write to: %1").arg(filePath));
|
||||
return;
|
||||
}
|
||||
|
||||
Utils::showInfo(this, "CSV export", QString("Transaction history exported to:\n\n%1").arg(filePath));
|
||||
}
|
||||
|
||||
HistoryExportDialog::~HistoryExportDialog() = default;
|
31
src/dialog/HistoryExportDialog.h
Normal file
31
src/dialog/HistoryExportDialog.h
Normal file
|
@ -0,0 +1,31 @@
|
|||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// SPDX-FileCopyrightText: The Monero Project
|
||||
|
||||
#ifndef HISTORYEXPORTDIALOG_H
|
||||
#define HISTORYEXPORTDIALOG_H
|
||||
|
||||
#include "components.h"
|
||||
|
||||
namespace Ui {
|
||||
class HistoryExportDialog;
|
||||
}
|
||||
|
||||
class Wallet;
|
||||
class HistoryExportDialog : public WindowModalDialog
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit HistoryExportDialog(Wallet *wallet, QWidget *parent);
|
||||
~HistoryExportDialog() override;
|
||||
|
||||
private:
|
||||
void setEverything();
|
||||
void exportHistory();
|
||||
|
||||
QScopedPointer<Ui::HistoryExportDialog> ui;
|
||||
Wallet *m_wallet;
|
||||
};
|
||||
|
||||
|
||||
#endif //HISTORYEXPORTDIALOG_H
|
302
src/dialog/HistoryExportDialog.ui
Normal file
302
src/dialog/HistoryExportDialog.ui
Normal file
|
@ -0,0 +1,302 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>HistoryExportDialog</class>
|
||||
<widget class="QDialog" name="HistoryExportDialog">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>351</width>
|
||||
<height>539</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="windowTitle">
|
||||
<string>History Export</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox">
|
||||
<property name="title">
|
||||
<string>Export range</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radio_everything">
|
||||
<property name="text">
|
||||
<string>Everything</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radio_YTD">
|
||||
<property name="text">
|
||||
<string>Year to Date</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radio_lastDays">
|
||||
<property name="text">
|
||||
<string>Last</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QSpinBox" name="spin_days">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="minimum">
|
||||
<number>1</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>99999</number>
|
||||
</property>
|
||||
<property name="value">
|
||||
<number>90</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>days</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_3">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radio_lastMonth">
|
||||
<property name="text">
|
||||
<string>Last month</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radio_lastYear">
|
||||
<property name="text">
|
||||
<string>Last year</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radio_customRange">
|
||||
<property name="text">
|
||||
<string>Custom range</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<spacer name="horizontalSpacer_2">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType">
|
||||
<enum>QSizePolicy::Policy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>From</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDateEdit" name="date_min">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="displayFormat">
|
||||
<string>yyyy-MM-dd</string>
|
||||
</property>
|
||||
<property name="calendarPopup">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>To</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDateEdit" name="date_max">
|
||||
<property name="enabled">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
<property name="displayFormat">
|
||||
<string>yyyy-MM-dd</string>
|
||||
</property>
|
||||
<property name="calendarPopup">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="title">
|
||||
<string>What to export</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radio_allTransactions">
|
||||
<property name="text">
|
||||
<string>All transactions</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radio_incomingTransactions">
|
||||
<property name="text">
|
||||
<string>Incoming transactions</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radio_outgoingTransactions">
|
||||
<property name="text">
|
||||
<string>Outgoing transactions</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QRadioButton" name="radio_coinbaseTransactions">
|
||||
<property name="text">
|
||||
<string>Coinbase (miner) transactions</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Line" name="line">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="check_excludePending">
|
||||
<property name="text">
|
||||
<string>Exclude pending transactions</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QCheckBox" name="check_excludeFailed">
|
||||
<property name="text">
|
||||
<string>Exclude failed transactions</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
<widget class="QPushButton" name="btn_export">
|
||||
<property name="text">
|
||||
<string>Export</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QDialogButtonBox" name="buttonBox">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Orientation::Horizontal</enum>
|
||||
</property>
|
||||
<property name="standardButtons">
|
||||
<set>QDialogButtonBox::StandardButton::Close</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>accepted()</signal>
|
||||
<receiver>HistoryExportDialog</receiver>
|
||||
<slot>accept()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>248</x>
|
||||
<y>254</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>157</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
<connection>
|
||||
<sender>buttonBox</sender>
|
||||
<signal>rejected()</signal>
|
||||
<receiver>HistoryExportDialog</receiver>
|
||||
<slot>reject()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel">
|
||||
<x>316</x>
|
||||
<y>260</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel">
|
||||
<x>286</x>
|
||||
<y>274</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
|
@ -342,68 +342,6 @@ void TransactionHistory::clearRows() {
|
|||
m_rows.clear();
|
||||
}
|
||||
|
||||
bool TransactionHistory::writeCSV(const QString &path) {
|
||||
QString data;
|
||||
QReadLocker locker(&m_lock);
|
||||
|
||||
auto transactions = m_rows;
|
||||
|
||||
std::sort(transactions.begin(), transactions.end(), [](const TransactionRow *info1, const TransactionRow *info2){
|
||||
return info1->blockHeight() < info2->blockHeight();
|
||||
});
|
||||
|
||||
for (const auto &info : transactions) {
|
||||
// collect column data
|
||||
QDateTime timeStamp = info->timestamp();
|
||||
double amount = info->amount();
|
||||
|
||||
// calc historical fiat price
|
||||
QString fiatAmount;
|
||||
QString preferredFiatSymbol = conf()->get(Config::preferredFiatCurrency).toString();
|
||||
const double usd_price = appData()->txFiatHistory->get(timeStamp.toString("yyyyMMdd"));
|
||||
double fiat_price = usd_price * amount;
|
||||
|
||||
if (preferredFiatSymbol != "USD")
|
||||
fiat_price = appData()->prices.convert("USD", preferredFiatSymbol, fiat_price);
|
||||
double fiat_rounded = ceil(Utils::roundSignificant(fiat_price, 3) * 100.0) / 100.0;
|
||||
if (usd_price != 0)
|
||||
fiatAmount = QString::number(fiat_rounded);
|
||||
else
|
||||
fiatAmount = "\"?\"";
|
||||
|
||||
QString direction = QString("");
|
||||
if (info->direction() == TransactionRow::Direction_In)
|
||||
direction = QString("in");
|
||||
else if (info->direction() == TransactionRow::Direction_Out)
|
||||
direction = QString("out");
|
||||
else
|
||||
continue; // skip TransactionInfo::Direction_Both
|
||||
|
||||
QString displayAmount = info->displayAmount();
|
||||
QString paymentId = info->paymentId();
|
||||
if (paymentId == "0000000000000000") {
|
||||
paymentId = "";
|
||||
}
|
||||
|
||||
QString date = QString("%1T%2Z").arg(info->date(), info->time()); // ISO 8601
|
||||
|
||||
QString balanceDelta = WalletManager::displayAmount(info->balanceDelta());
|
||||
if (info->direction() == TransactionRow::Direction_Out) {
|
||||
balanceDelta = "-" + balanceDelta;
|
||||
}
|
||||
|
||||
// format and write
|
||||
QString line = QString("\n%1,%2,\"%3\",%4,\"%5\",%6,%7,%8,\"%9\",\"%10\",\"%11\",%12,\"%13\"")
|
||||
.arg(QString::number(info->blockHeight()), QString::number(timeStamp.toSecsSinceEpoch()), date,
|
||||
QString::number(info->subaddrAccount()), direction, balanceDelta, info->displayAmount(),
|
||||
info->fee(), info->hash(), info->description(), paymentId, fiatAmount, preferredFiatSymbol);
|
||||
data += line;
|
||||
}
|
||||
|
||||
data = QString("blockHeight,timestamp,date,accountIndex,direction,balanceDelta,amount,fee,txid,description,paymentId,fiatAmount,fiatCurrency%1").arg(data);
|
||||
return Utils::fileWrite(path, data);
|
||||
}
|
||||
|
||||
QStringList parseCSVLine(const QString &line) {
|
||||
QStringList result;
|
||||
QString currentField;
|
||||
|
|
|
@ -41,7 +41,6 @@ public:
|
|||
bool locked() const;
|
||||
void clearRows();
|
||||
|
||||
bool writeCSV(const QString &path);
|
||||
QString importLabelsFromCSV(const QString &fileName);
|
||||
|
||||
signals:
|
||||
|
|
Loading…
Reference in a new issue