btcpayserver/BTCPayServer/Services/Wallets/Export/TransactionsExport.cs
d11n d5d0be5824
Code formatting updates (#4502)
* Editorconfig: Add space_before_self_closing setting

This was a difference between the way dotnet-format and Rider format code. See https://www.jetbrains.com/help/rider/EditorConfig_Index.html

* Editorconfig: Keep 4 spaces indentation for Swagger JSON files

They are all formatted that way, let's keep it like that.

* Apply dotnet-format, mostly white-space related changes
2023-01-06 22:18:07 +09:00

100 lines
3.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using BTCPayServer.Client.Models;
using BTCPayServer.Data;
using BTCPayServer.Models.WalletViewModels;
using BTCPayServer.Services.Invoices;
using BTCPayServer.Services.Rates;
using CsvHelper.Configuration;
using CsvHelper.Configuration.Attributes;
using NBXplorer.Models;
using Newtonsoft.Json;
namespace BTCPayServer.Services.Wallets.Export
{
public class TransactionsExport
{
private readonly BTCPayWallet _wallet;
private readonly Dictionary<string, WalletTransactionInfo> _walletTransactionsInfo;
public TransactionsExport(BTCPayWallet wallet, Dictionary<string, WalletTransactionInfo> walletTransactionsInfo)
{
_wallet = wallet;
_walletTransactionsInfo = walletTransactionsInfo;
}
public string Process(IEnumerable<TransactionHistoryLine> inputList, string fileFormat)
{
var list = inputList.Select(tx =>
{
var model = new ExportTransaction
{
TransactionId = tx.TransactionId.ToString(),
Timestamp = tx.SeenAt,
Amount = tx.BalanceChange.ShowMoney(_wallet.Network),
Currency = _wallet.Network.CryptoCode,
IsConfirmed = tx.Confirmations != 0
};
if (_walletTransactionsInfo.TryGetValue(tx.TransactionId.ToString(), out var transactionInfo))
{
model.Labels = transactionInfo.LabelColors?.Select(l => l.Key).ToList();
model.Comment = transactionInfo.Comment;
}
return model;
}).ToList();
if (string.Equals(fileFormat, "json", StringComparison.OrdinalIgnoreCase))
return ProcessJson(list);
if (string.Equals(fileFormat, "csv", StringComparison.OrdinalIgnoreCase))
return ProcessCsv(list);
throw new Exception("Export format not supported");
}
private static string ProcessJson(List<ExportTransaction> invoices)
{
var serializerSett = new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore };
var json = JsonConvert.SerializeObject(invoices, Formatting.Indented, serializerSett);
return json;
}
private static string ProcessCsv(IEnumerable<ExportTransaction> invoices)
{
using StringWriter writer = new();
using var csvWriter = new CsvHelper.CsvWriter(writer, new CsvConfiguration(CultureInfo.InvariantCulture), true);
csvWriter.Configuration.RegisterClassMap<ExportTransactionMap>();
csvWriter.WriteHeader<ExportTransaction>();
csvWriter.NextRecord();
csvWriter.WriteRecords(invoices);
csvWriter.Flush();
return writer.ToString();
}
}
public sealed class ExportTransactionMap : ClassMap<ExportTransaction>
{
public ExportTransactionMap()
{
AutoMap(CultureInfo.InvariantCulture);
Map(m => m.Labels).ConvertUsing(row => row.Labels == null ? string.Empty : string.Join(", ", row.Labels));
}
}
public class ExportTransaction
{
[Name("Transaction Id")]
public string TransactionId { get; set; }
public DateTimeOffset Timestamp { get; set; }
public string Amount { get; set; }
public string Currency { get; set; }
[Name("Is Confirmed")]
public bool IsConfirmed { get; set; }
public string Comment { get; set; }
public List<string> Labels { get; set; }
}
}