mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2026-01-26 09:24:28 +01:00
* mark items to abstract wip wip wip wip wip wip wip cleanup parse other types compile and fix tests fix bug fix warnings fix rebase error reduce payment method handler passings more cleanup switch tests to Fast mode fix obsolete warning remove argument requirement rebase fixes remove overcomplicated code better parsing remove dependency on environement remove async * fixes and simplification * simplify * clean up even more * replace nuglify dependency * remove extra space * Fix tests * fix booboo * missing setter * change url resolver * reduce payment method handlers * wrap payment method handlers in a custom type * fix tests * make invoice controller UI selectlist population cleaner * make store controller use payment handler dictionary * fix ln flag * fix store controller test * remove null checks on payment handlers * remove unused imports * BitcoinSpecificBtcPayNetwork - abstract BTCPayNetwork * some type fixes * fix tests * simplify fetching handler in invoice controller * rename network base and bitcoin classes * abstract serializer to network level * fix serializer when network not provided * fix serializer when network not provided * fix serializer when network not provided * Abstract more payment type specific logic to handlers * fix merge issue * small fixes * make use of repository instead of direct context usage * reduce redundant code * sanity check * test fixes
147 lines
6.6 KiB
C#
147 lines
6.6 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using BTCPayServer.Payments;
|
|
using BTCPayServer.Payments.Bitcoin;
|
|
using BTCPayServer.Services.Invoices;
|
|
using BTCPayServer.Services.Rates;
|
|
using Newtonsoft.Json;
|
|
|
|
namespace BTCPayServer.Services.Invoices.Export
|
|
{
|
|
public class InvoiceExport
|
|
{
|
|
public BTCPayNetworkProvider Networks { get; }
|
|
public CurrencyNameTable Currencies { get; }
|
|
|
|
public InvoiceExport(BTCPayNetworkProvider networks, CurrencyNameTable currencies)
|
|
{
|
|
Networks = networks;
|
|
Currencies = currencies;
|
|
}
|
|
public string Process(InvoiceEntity[] invoices, string fileFormat)
|
|
{
|
|
var csvInvoices = new List<ExportInvoiceHolder>();
|
|
foreach (var i in invoices)
|
|
{
|
|
csvInvoices.AddRange(convertFromDb(i));
|
|
}
|
|
|
|
if (String.Equals(fileFormat, "json", StringComparison.OrdinalIgnoreCase))
|
|
return processJson(csvInvoices);
|
|
else if (String.Equals(fileFormat, "csv", StringComparison.OrdinalIgnoreCase))
|
|
return processCsv(csvInvoices);
|
|
else
|
|
throw new Exception("Export format not supported");
|
|
}
|
|
|
|
private string processJson(List<ExportInvoiceHolder> invoices)
|
|
{
|
|
var serializerSett = new JsonSerializerSettings { ReferenceLoopHandling = ReferenceLoopHandling.Ignore };
|
|
var json = JsonConvert.SerializeObject(invoices, Formatting.Indented, serializerSett);
|
|
|
|
return json;
|
|
}
|
|
|
|
private string processCsv(List<ExportInvoiceHolder> invoices)
|
|
{
|
|
var serializer = new CsvSerializer<ExportInvoiceHolder>();
|
|
var csv = serializer.Serialize(invoices);
|
|
|
|
return csv;
|
|
}
|
|
|
|
private IEnumerable<ExportInvoiceHolder> convertFromDb(InvoiceEntity invoice)
|
|
{
|
|
var exportList = new List<ExportInvoiceHolder>();
|
|
var currency = Currencies.GetNumberFormatInfo(invoice.ProductInformation.Currency, true);
|
|
|
|
var invoiceDue = invoice.ProductInformation.Price;
|
|
// in this first version we are only exporting invoices that were paid
|
|
foreach (var payment in invoice.GetPayments())
|
|
{
|
|
// not accounted payments are payments which got double spent like RBfed
|
|
if (!payment.Accounted)
|
|
continue;
|
|
var cryptoCode = payment.GetPaymentMethodId().CryptoCode;
|
|
var pdata = payment.GetCryptoPaymentData();
|
|
|
|
var pmethod = invoice.GetPaymentMethod(payment.GetPaymentMethodId(), Networks);
|
|
var paidAfterNetworkFees = pdata.GetValue() - payment.NetworkFee;
|
|
invoiceDue -= paidAfterNetworkFees * pmethod.Rate;
|
|
|
|
var target = new ExportInvoiceHolder
|
|
{
|
|
ReceivedDate = payment.ReceivedTime.UtcDateTime,
|
|
PaymentId = pdata.GetPaymentId(),
|
|
CryptoCode = cryptoCode,
|
|
ConversionRate = pmethod.Rate,
|
|
PaymentType = invoice.PaymentMethodHandlerDictionary[payment.GetPaymentMethodId()].PrettyDescription,
|
|
Destination = payment.GetCryptoPaymentData().GetDestination(Networks.GetNetwork<BTCPayNetworkBase>(cryptoCode)),
|
|
Paid = pdata.GetValue().ToString(CultureInfo.InvariantCulture),
|
|
PaidCurrency = Math.Round(pdata.GetValue() * pmethod.Rate, currency.NumberDecimalDigits).ToString(CultureInfo.InvariantCulture),
|
|
// Adding NetworkFee because Paid doesn't take into account network fees
|
|
// so if fee is 10000 satoshis, customer can essentially send infinite number of tx
|
|
// and merchant effectivelly would receive 0 BTC, invoice won't be paid
|
|
// while looking just at export you could sum Paid and assume merchant "received payments"
|
|
NetworkFee = payment.NetworkFee.ToString(CultureInfo.InvariantCulture),
|
|
InvoiceDue = Math.Round(invoiceDue, currency.NumberDecimalDigits),
|
|
OrderId = invoice.OrderId,
|
|
StoreId = invoice.StoreId,
|
|
InvoiceId = invoice.Id,
|
|
InvoiceCreatedDate = invoice.InvoiceTime.UtcDateTime,
|
|
InvoiceExpirationDate = invoice.ExpirationTime.UtcDateTime,
|
|
InvoiceMonitoringDate = invoice.MonitoringExpiration.UtcDateTime,
|
|
#pragma warning disable CS0618 // Type or member is obsolete
|
|
InvoiceFullStatus = invoice.GetInvoiceState().ToString(),
|
|
InvoiceStatus = invoice.StatusString,
|
|
InvoiceExceptionStatus = invoice.ExceptionStatusString,
|
|
#pragma warning restore CS0618 // Type or member is obsolete
|
|
InvoiceItemCode = invoice.ProductInformation.ItemCode,
|
|
InvoiceItemDesc = invoice.ProductInformation.ItemDesc,
|
|
InvoicePrice = invoice.ProductInformation.Price,
|
|
InvoiceCurrency = invoice.ProductInformation.Currency,
|
|
BuyerEmail = invoice.BuyerInformation?.BuyerEmail
|
|
};
|
|
|
|
exportList.Add(target);
|
|
}
|
|
|
|
exportList = exportList.OrderBy(a => a.ReceivedDate).ToList();
|
|
|
|
return exportList;
|
|
}
|
|
}
|
|
|
|
public class ExportInvoiceHolder
|
|
{
|
|
public DateTime ReceivedDate { get; set; }
|
|
public string StoreId { get; set; }
|
|
public string OrderId { get; set; }
|
|
public string InvoiceId { get; set; }
|
|
public DateTime InvoiceCreatedDate { get; set; }
|
|
public DateTime InvoiceExpirationDate { get; set; }
|
|
public DateTime InvoiceMonitoringDate { get; set; }
|
|
|
|
public string PaymentId { get; set; }
|
|
public string Destination { get; set; }
|
|
public string PaymentType { get; set; }
|
|
public string CryptoCode { get; set; }
|
|
public string Paid { get; set; }
|
|
public string NetworkFee { get; set; }
|
|
public decimal ConversionRate { get; set; }
|
|
public string PaidCurrency { get; set; }
|
|
public string InvoiceCurrency { get; set; }
|
|
public decimal InvoiceDue { get; set; }
|
|
public decimal InvoicePrice { get; set; }
|
|
public string InvoiceItemCode { get; set; }
|
|
public string InvoiceItemDesc { get; set; }
|
|
public string InvoiceFullStatus { get; set; }
|
|
public string InvoiceStatus { get; set; }
|
|
public string InvoiceExceptionStatus { get; set; }
|
|
public string BuyerEmail { get; set; }
|
|
}
|
|
}
|