using Bit.Core.Billing.Commands; using Bit.Core.Billing.Constants; using Bit.Core.Billing.Payment.Models; using Bit.Core.Services; using Microsoft.Extensions.Logging; using Stripe; namespace Bit.Core.Billing.Premium.Commands; using static StripeConstants; public interface IPreviewPremiumTaxCommand { Task> Run( int additionalStorage, BillingAddress billingAddress); } public class PreviewPremiumTaxCommand( ILogger logger, IStripeAdapter stripeAdapter) : BaseBillingCommand(logger), IPreviewPremiumTaxCommand { public Task> Run( int additionalStorage, BillingAddress billingAddress) => HandleAsync<(decimal, decimal)>(async () => { var options = new InvoiceCreatePreviewOptions { AutomaticTax = new InvoiceAutomaticTaxOptions { Enabled = true }, CustomerDetails = new InvoiceCustomerDetailsOptions { Address = new AddressOptions { Country = billingAddress.Country, PostalCode = billingAddress.PostalCode } }, Currency = "usd", SubscriptionDetails = new InvoiceSubscriptionDetailsOptions { Items = [ new InvoiceSubscriptionDetailsItemOptions { Price = Prices.PremiumAnnually, Quantity = 1 } ] } }; if (additionalStorage > 0) { options.SubscriptionDetails.Items.Add(new InvoiceSubscriptionDetailsItemOptions { Price = Prices.StoragePlanPersonal, Quantity = additionalStorage }); } var invoice = await stripeAdapter.InvoiceCreatePreviewAsync(options); return GetAmounts(invoice); }); private static (decimal, decimal) GetAmounts(Invoice invoice) => ( Convert.ToDecimal(invoice.TotalTaxes.Sum(invoiceTotalTax => invoiceTotalTax.Amount)) / 100, Convert.ToDecimal(invoice.Total) / 100); }