using Bit.Core.Enums; using Bit.Core.Models.Table; using Stripe; using System; using System.Collections.Generic; namespace Bit.Core.Models.Business { public class BillingInfo { public decimal Balance { get; set; } public BillingSource PaymentSource { get; set; } public IEnumerable Invoices { get; set; } = new List(); public IEnumerable Transactions { get; set; } = new List(); public class BillingSource { public BillingSource() { } public BillingSource(PaymentMethod method) { if (method.Card != null) { Type = PaymentMethodType.Card; Description = $"{method.Card.Brand?.ToUpperInvariant()}, *{method.Card.Last4}, " + string.Format("{0}/{1}", string.Concat(method.Card.ExpMonth < 10 ? "0" : string.Empty, method.Card.ExpMonth), method.Card.ExpYear); CardBrand = method.Card.Brand; } } public BillingSource(IPaymentSource source) { if (source is BankAccount bankAccount) { Type = PaymentMethodType.BankAccount; Description = $"{bankAccount.BankName}, *{bankAccount.Last4} - " + (bankAccount.Status == "verified" ? "verified" : bankAccount.Status == "errored" ? "invalid" : bankAccount.Status == "verification_failed" ? "verification failed" : "unverified"); NeedsVerification = bankAccount.Status == "new" || bankAccount.Status == "validated"; } else if (source is Card card) { Type = PaymentMethodType.Card; Description = $"{card.Brand}, *{card.Last4}, " + string.Format("{0}/{1}", string.Concat(card.ExpMonth < 10 ? "0" : string.Empty, card.ExpMonth), card.ExpYear); CardBrand = card.Brand; } else if (source is Source src && src.Card != null) { Type = PaymentMethodType.Card; Description = $"{src.Card.Brand}, *{src.Card.Last4}, " + string.Format("{0}/{1}", string.Concat(src.Card.ExpMonth < 10 ? "0" : string.Empty, src.Card.ExpMonth), src.Card.ExpYear); CardBrand = src.Card.Brand; } } public BillingSource(Braintree.PaymentMethod method) { if (method is Braintree.PayPalAccount paypal) { Type = PaymentMethodType.PayPal; Description = paypal.Email; } else if (method is Braintree.CreditCard card) { Type = PaymentMethodType.Card; Description = $"{card.CardType.ToString()}, *{card.LastFour}, " + string.Format("{0}/{1}", string.Concat(card.ExpirationMonth.Length == 1 ? "0" : string.Empty, card.ExpirationMonth), card.ExpirationYear); CardBrand = card.CardType.ToString(); } else if (method is Braintree.UsBankAccount bank) { Type = PaymentMethodType.BankAccount; Description = $"{bank.BankName}, *{bank.Last4}"; } else { throw new NotSupportedException("Method not supported."); } } public BillingSource(Braintree.UsBankAccountDetails bank) { Type = PaymentMethodType.BankAccount; Description = $"{bank.BankName}, *{bank.Last4}"; } public BillingSource(Braintree.PayPalDetails paypal) { Type = PaymentMethodType.PayPal; Description = paypal.PayerEmail; } public PaymentMethodType Type { get; set; } public string CardBrand { get; set; } public string Description { get; set; } public bool NeedsVerification { get; set; } } public class BillingTransaction { public BillingTransaction(Transaction transaction) { Id = transaction.Id; CreatedDate = transaction.CreationDate; Refunded = transaction.Refunded; Type = transaction.Type; PaymentMethodType = transaction.PaymentMethodType; Details = transaction.Details; Amount = transaction.Amount; RefundedAmount = transaction.RefundedAmount; } public Guid Id { get; set; } public DateTime CreatedDate { get; set; } public decimal Amount { get; set; } public bool? Refunded { get; set; } public bool? PartiallyRefunded => !Refunded.GetValueOrDefault() && RefundedAmount.GetValueOrDefault() > 0; public decimal? RefundedAmount { get; set; } public TransactionType Type { get; set; } public PaymentMethodType? PaymentMethodType { get; set; } public string Details { get; set; } } public class BillingInvoice { public BillingInvoice(Invoice inv) { Amount = inv.AmountDue / 100M; Date = inv.Created; Url = inv.HostedInvoiceUrl; PdfUrl = inv.InvoicePdf; Number = inv.Number; Paid = inv.Paid; Amount = inv.Total / 100M; } public decimal Amount { get; set; } public DateTime? Date { get; set; } public string Url { get; set; } public string PdfUrl { get; set; } public string Number { get; set; } public bool Paid { get; set; } } } }