using System; using System.ComponentModel.DataAnnotations; using System.Threading.Tasks; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using MisIngredientesVue.Core.Extensions; using MisIngredientesVue.Core.Models; using MisIngredientesVue.Core.Services; using Newtonsoft.Json; namespace MisIngredientesVue.Controllers { [Route("api/[controller]")] [ApiController] public class BillingController : Controller { //private readonly string TEST_SUBSCRIPTION_ID = "sub_IfJ22rtBeNgVGi"; //Subscripción de usuario //private readonly string TEST_SUBSUBSCRIPTION_ID = "sub_IeV2va87PXJbPD"; //Subscripción de folios de facturación private readonly IBillingService _billingService; private readonly IEmailService _emailService; private readonly IInvoicingService _invoicingService; private readonly IUsersService _usersService; private readonly ISettingsService _settingsService; private readonly IAuthenticationTokenService _authenticationTokenService; public BillingController(IBillingService billingService, IAuthenticationTokenService authenticationTokenService, IUsersService usersService, IInvoicingService invoicingService, ISettingsService settingsService, IEmailService emailService) { _billingService = billingService; _authenticationTokenService = authenticationTokenService; _usersService = usersService; _invoicingService = invoicingService; _settingsService = settingsService; _emailService = emailService; } [AllowAnonymous] [HttpGet("plans")] public async Task GetPlans() { return Ok(await _billingService.GetPlans()); } [HttpGet("cards")] public async Task GetCards() { var customerId = await EnsureCustomerId(); var res = await _billingService.GetPaymentMethods(User.Identity.GetTenantId(), customerId, User.Identity.Name, "card"); if (res.refreshToken) { await RefreshJsonToken(); } return Ok(res.paymentMethods); } [HttpGet("subscription")] public async Task GetSubscription() { var sub = await _billingService.GetSubscription(User.Identity.GetSubscriptionId(), User.Identity.GetSubSubscriptionId()); sub.PlanId = User.Identity.GetPlanId(); return Ok(sub); } [HttpGet("trialdays")] public async Task GetLeftTrialDays() { return Ok(new { days = User.Identity.GetLeftTrialDays() }); } [HttpPut("cards/delete")] public async Task DeleteCards(string[] ids) { var customerId = await EnsureCustomerId(); await _billingService.DeleteCards(User.Identity.GetTenantId(), customerId, ids); return Ok(); } [AllowAnonymous] [HttpPost("newsubscription")] public async Task CreateNewSubscription(CreateNewSubscriptionRequest request) { var user = await _billingService.CreateNewSubscription(request.PlanTypeId, request.PaymentId, request.Email, request.FirstName, request.LastName, request.Password, request.CompanyName); await _settingsService.SaveSettings(user.TenantId, new System.Collections.Generic.List() { new ClientSetting() { Name = ClientSettingType.CompanyName, Value = request.CompanyName } }); var code = await _usersService.GenerateResetPasswordCode(request.Email); var url = $"{Request.Scheme}://{Request.Host}{Request.PathBase}/verification?code={code}"; var emailBody = await _settingsService.GetEmailTemplateBody(null, EmailTemplateKey.UsersConfirmation); _emailService.SendEmail(false, "noreply@misingredientes.mx", new string[] { request.Email }, "Mis Ingredientes - Confirme su dirección de correo", emailBody.Replace("[LINK]", url), true); //var token = await _authenticationTokenService.GetTokenForUser(user.TenantId, user, new InvoicingInfo()); //Response.Headers.Add("x-refresh-token", token.Token); return Ok(); } //[AllowAnonymous] //[HttpPost("newsubscriptionnocard")] //public async Task CreateNewSubscriptionNoCard(CreateNewSubscriptionRequest request) //{ // var user = await _billingService.CreateNewSubscriptionNoCard(request.PlanTypeId, // request.Email, request.FirstName, request.LastName, request.Password, request.CompanyName); // await _settingsService.SaveSettings(user.TenantId, new System.Collections.Generic.List() // { // new ClientSetting() { Name = ClientSettingType.CompanyName, Value = request.CompanyName } // }); // var code = await _usersService.GenerateResetPasswordCode(request.Email); // var url = $"{Request.Scheme}://{Request.Host}{Request.PathBase}/verification?code={code}"; // var emailBody = await _settingsService.GetEmailTemplateBody(null, EmailTemplateKey.UsersConfirmation); // _emailService.SendEmail(false, "noreply@misingredientes.mx", new string[] { request.Email }, // "Mis Ingredientes - Confirme su dirección de correo", emailBody.Replace("[LINK]", url), true); // //var token = await _authenticationTokenService.GetTokenForUser(user.TenantId, user, new InvoicingInfo()); // //Response.Headers.Add("x-refresh-token", token.Token); // return Ok(); //} [HttpGet("usage")] public async Task GetUsage() { //return Ok(await _billingService.GetUsage(TEST_SUBSUBSCRIPTION_ID)); return Ok(await _billingService.GetUsage(User.Identity.GetSubSubscriptionId())); } [HttpPost("subscription")] public async Task CreateOrUpdateSubscription([FromBody] CreateSubscriptionRequest req) { if (string.IsNullOrEmpty(req.PlanTypeId) || !int.TryParse(req.PlanTypeId, out _)) return BadRequest(); var planType = (PlanType)Convert.ToInt32(req.PlanTypeId); if (planType == PlanType.BasicMonthly || planType == PlanType.BasicYearly) return BadRequest(); //Para el plan gratis no es necesario pagar if (planType != PlanType.FreeMonthly && planType != PlanType.FreeYearly && string.IsNullOrEmpty(req.PaymentMethodId)) return BadRequest(); var tenantId = User.Identity.GetTenantId(); if (string.IsNullOrEmpty(tenantId)) return BadRequest(); var customerId = await EnsureCustomerId(); var userSubscription = await _billingService.CreateOrUpdateSubscription(tenantId, customerId, User.Identity.GetSubscriptionId(), User.Identity.GetSubSubscriptionId(), req.PaymentMethodId, req.PlanTypeId); await RefreshJsonToken(); return Ok(userSubscription); } [HttpPost("test")] public async Task DeleteMe() //DELETE ME { return Ok(); //await _billingService.Test(User.Identity.GetStripeCustomerId()); await _invoicingService.ReportUsage(User.Identity.GetTenantId(), User.Identity.GetSubSubscriptionItemId(), User.Identity.GetUserId(), "Prueba1", "Prueba2", CfdiRecordType.Invoice, CfdiRecordStatus.Generated); return Ok(); } [HttpGet("upcominginvoice")] public async Task GetUpcomingInvoice() { //return Ok(await _billingService.GetUpcomingInvoice(TEST_SUBSCRIPTION_ID, TEST_SUBSUBSCRIPTION_ID)); //return Ok(await _billingService.GetUpcomingInvoice("sub_IeV2va87PXJbPD")); return Ok(await _billingService.GetUpcomingInvoice(User.Identity.GetSubscriptionId(), User.Identity.GetSubSubscriptionId())); } [HttpGet("folios")] public async Task GetFolios(int skip, int take, string sortBy, string sortOrder, long startDate, long endDate) { var data = await _billingService.GetCfdiUsageRecords(User.Identity.GetTenantId(), skip, take, sortBy, sortOrder, DateTime.FromFileTimeUtc(startDate), DateTime.FromFileTimeUtc(endDate)); var usage = await _billingService.GetUsage(User.Identity.GetSubSubscriptionId()); if (usage.Qty > 0) { var free = data.Total - usage.Qty; if(free >= skip) { var counter = free - skip; foreach(var item in data.Results) { counter--; if(counter < 0) item.Cost = usage.Cost; } } } return Ok(new PagedResults(data.Results, data.Total, skip, take, sortBy, sortOrder)); } [HttpPost("foliosexcel")] public async Task GetFoliosExcel(string sortBy, string sortOrder, long startDate, long endDate) { var memoryStream = await _billingService.GetCfdiUsageRecordsExcel(User.Identity.GetTenantId(), User.Identity.GetTimeOffset(), sortBy, sortOrder, DateTime.FromFileTimeUtc(startDate), DateTime.FromFileTimeUtc(endDate)); return File(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); } private async Task EnsureCustomerId() { var customerId = User.Identity.GetStripeCustomerId(); if (string.IsNullOrEmpty(customerId)) { var customer = await _billingService.CreateCustomer(User.Identity.GetTenantId(), User.Identity.Name); customerId = customer.Id; } return customerId; } private async Task RefreshJsonToken() { var invoicingInfo = await _invoicingService.GetInvoicingInfo(User.Identity.GetTenantId()); var user = await _usersService.GetUser(User.Identity.GetTenantId(), User.Identity.GetUserId(), User.Identity.IsClient()); var newToken = await _authenticationTokenService.GetTokenForUser(User.Identity.GetTenantId(), user, invoicingInfo); Response.Headers.Add("x-refresh-token", newToken.Token); } } public class CreateNewSubscriptionRequest { public string PlanTypeId { get; set; } public string PaymentId { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public string Password { get; set; } public string Email { get; set; } public string CompanyName { get; set; } } public class CreateSubscriptionRequest { public string PaymentMethodId { get; set; } [Required] public string PlanTypeId { get; set; } } }