using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Threading.Tasks; using Dapper; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.JsonPatch; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Abstractions; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.SignalR; using MisIngredientesVue.Core.Exceptions; using MisIngredientesVue.Core.Extensions; using MisIngredientesVue.Core.Models; using MisIngredientesVue.Core.Services; using MisIngredientesVue.Hubs; using Newtonsoft.Json; using Newtonsoft.Json.Linq; using Wkhtmltopdf.NetCore; namespace MisIngredientesVue.Controllers { [Route("api/[controller]")] [ApiController] public class OrdersController : Controller { private readonly IOrdersService _ordersService; private readonly IHubContext _hubcontext; private readonly IServiceProvider _serviceProvider; private readonly IUsersService _usersService; private readonly IHostingEnvironment _env; readonly IGeneratePdf _generatePdf; public OrdersController( IHubContext hubcontext, IHostingEnvironment env, IGeneratePdf generatePdf, IUsersService usersService, IServiceProvider serviceProvider, IOrdersService ordersService) { _ordersService = ordersService; _hubcontext = hubcontext; _env = env; _generatePdf = generatePdf; _usersService = usersService; _serviceProvider = serviceProvider; } [Route("{id}")] [HttpGet] public async Task Get(int id) { if (!User.Identity.IsClient()) { var order = await _ordersService.GetOrderById(User.Identity.GetTenantId(), User.Identity.GetUserId(), id); if (order == null) return NotFound(); var total = _ordersService.CalculateTotal(order); Console.WriteLine(total.Subtotal + " " + total.Total); return Ok(order); } else { var order = await _ordersService.GetClientOrderById(User.Identity.GetTenantId(), User.Identity.GetUserId(), id); if (order == null) return NotFound(); return Ok(order); } } [Route("{id}")] [HttpPut] public async Task Put(int id, Order order) { if (id != order.Id) return BadRequest(); if (User.Identity.IsClient()) { await _ordersService.UpdateClientOrder(User.Identity.GetTenantId(), User.Identity.GetUserId(), order); return Ok(); } else { await _ordersService.UpdateOrder(User.Identity.GetTenantId(), User.Identity.GetUserId(), order); return Ok(); } } [HttpGet] public async Task Get(string q, int skip, int take, string sortBy, string sortOrder, string deliveryStatus = null, string paymentStatus = null, decimal? total = null, string client = null, int? id = null, string branch = null, string brand = null, string deliveryDate = null, string promisedPaymentDate = null, string actualPaymentDate = null, string name = null, string legalName = null, int? invoiceId = null, int offset = 0, int includeCancelled = 0, int? invoiceStatus = null) { if (User.Identity.IsClient()) { var findAll = await _ordersService.GetClientOrders(User.Identity.GetTenantId(), q, skip, take, sortBy, sortOrder, id, deliveryStatus, paymentStatus, total, client, branch, brand, deliveryDate, promisedPaymentDate, actualPaymentDate, invoiceId, includeCancelled, invoiceStatus, name, legalName); return Ok(new PagedResults(findAll.Results, findAll.Total, skip, take) { Filters = findAll.Filters, CustomData = findAll.CustomData }); } else { var findAll = await _ordersService.GetOrders(User.Identity.GetTenantId(), q, skip, take, sortBy, sortOrder, id, deliveryStatus, paymentStatus, total, client, branch, brand, deliveryDate, promisedPaymentDate, actualPaymentDate, invoiceId, includeCancelled, invoiceStatus); return Ok(new PagedResults(findAll.Results, findAll.Total, skip, take) { Filters = findAll.Filters, CustomData = findAll.CustomData }); } } [Route("filters")] [HttpGet] public async Task GetFilters(string type, string q, int skip, int take, string sortBy, string sortOrder, string deliveryStatus = null, string paymentStatus = null, decimal? total = null, string client = null, int? id = null, string branch = null, string brand = null, string deliveryDate = null, string promisedPaymentDate = null, string actualPaymentDate = null, int? invoiceId = null, int offset = 0, int includeCancelled = 0, int? invoiceStatus = null) { return Ok(await _ordersService.GetFilters(User.Identity.GetTenantId(), type, q, id, deliveryStatus, paymentStatus, total, client, branch, brand, deliveryDate, promisedPaymentDate, actualPaymentDate, invoiceId, includeCancelled, invoiceStatus)); } [Route("clientfilters")] [HttpGet] public async Task GetClientFilters(string type, string q, int skip, int take, string sortBy, string sortOrder, string deliveryStatus = null, string paymentStatus = null, decimal? total = null, string client = null, int? id = null, string branch = null, string brand = null, string deliveryDate = null, string promisedPaymentDate = null, string actualPaymentDate = null, string name = null, string legalName = null, int? invoiceId = null, int offset = 0, int includeCancelled = 0, int? invoiceStatus = null) { return Ok(await _ordersService.GetClientFilters(User.Identity.GetTenantId(), type, q, id, deliveryStatus, paymentStatus, total, client, branch, brand, deliveryDate, promisedPaymentDate, actualPaymentDate, invoiceId, includeCancelled, invoiceStatus, name, legalName)); } [Route("customdata")] [HttpGet] public async Task GetCustomData(string q, int skip, int take, string sortBy, string sortOrder, string deliveryStatus = null, string paymentStatus = null, decimal? total = null, string client = null, int? id = null, string branch = null, string brand = null, string deliveryDate = null, string promisedPaymentDate = null, string actualPaymentDate = null, int? invoiceId = null, int offset = 0, int includeCancelled = 0, int? invoiceStatus = null) { var findAll = await _ordersService.GetOrders(User.Identity.GetTenantId(), q, skip, take, sortBy, sortOrder, id, deliveryStatus, paymentStatus, total, client, branch, brand, deliveryDate, promisedPaymentDate, actualPaymentDate, invoiceId, includeCancelled, invoiceStatus); return Ok(findAll.CustomData); } //https://localhost:5001/api/orders?q=&skip=0&take=25&sortBy=&sortOrder=asc&id=1&client=1&branch=1&deliveryDate=2020-01-07,2020-01-30&total=200&deliveryStatus=1&paymentStatus=0,1&promisedPaymentDate=2020-01-21,2020-01-31&actualPaymentDate=2020-01-14,2020-01-31 [Route("excel")] [HttpPost] public async Task GetExcel(string q, int skip, int take, string sortBy, string sortOrder, string deliveryStatus = null, string paymentStatus = null, decimal? total = null, string client = null, int? id = null, string branch = null, string brand = null, string deliveryDate = null, string promisedPaymentDate = null, string actualPaymentDate = null, string name = null, string legalName = null, int? invoiceId = null, int includeCancelled = 0, int? invoiceStatus = null) { if (!User.Identity.IsClient()) { var memoryStream = await _ordersService.GetExcel(User.Identity.GetTenantId(), Request.GetTimeOffset(), q, sortBy, sortOrder, id, deliveryStatus, paymentStatus, total, client, branch, brand, deliveryDate, promisedPaymentDate, actualPaymentDate, invoiceId, includeCancelled, invoiceStatus); return File(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); } else { var memoryStream = await _ordersService.GetClientExcel(User.Identity.GetTenantId(), Request.GetTimeOffset(), q, sortBy, sortOrder, id, deliveryStatus, paymentStatus, total, client, branch, brand, deliveryDate, promisedPaymentDate, actualPaymentDate, invoiceId, includeCancelled, invoiceStatus, name, legalName); return File(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); } } [Route("excelfromdata")] [HttpPost] public async Task GetExcelFromData(OrderProduct[] products) { var memoryStream = await _ordersService.GetExcelFromData(products, Request.GetTimeOffset()); return File(memoryStream, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); } [Route("{id}")] [HttpPatch] public async Task Patch(int id, [FromBody]JsonPatchDocument changes) { var order = await _ordersService.PatchOrder(User.Identity.GetTenantId(), User.Identity.GetUserId(), id, changes); //await _hubcontext.Clients.All.SendAsync("ReceiveMessage", User.Identity.GetFullName(), $"Realiz� modificaciones al pedido {order.Folio}"); return Ok(order); } [Route("{id}/payments")] [HttpPost] public async Task InsertPayment(int id, [FromBody]AddPaymentRequest request) { return Ok(await _ordersService.InsertPayment(User.Identity.GetTenantId(), User.Identity.GetUserId(), id, request.Date, request.Amount)); } [Route("updateaccesstime")] [HttpPost] public async Task UpdateAccessTime([FromBody]UpdateAccessTimeRequest updateAccessTimeRequest) { await _ordersService.UpdateAccessTime(User.Identity.GetTenantId(), User.Identity.GetUserId(), updateAccessTimeRequest.OrderIds); return Ok(); } [Route("{id}/clearaccesstime")] [HttpPost] public async Task ClearAccessTime(int id) { await _ordersService.ClearAccessTime(User.Identity.GetTenantId(), User.Identity.GetUserId(), id); return Ok(); } [Route("{id}/payments")] [HttpGet] public async Task GetOrderPayments(int id) { return Ok(await _ordersService.GetOrderPayments(User.Identity.GetTenantId(), id)); } [Route("{id}/alloweddates")] [HttpGet] public async Task GetAllowedDates(int id) { return Ok(await _ordersService.GetAllowedDates(User.Identity.GetTenantId(), id)); } [Route("{id}/setpaymentdate")] [HttpPost] public async Task SetPaymentDate(int id, [FromBody] SetLastPaymentDateRequest request) { await _ordersService.SetPaymentDate(User.Identity.GetTenantId(), id, request.PaymentId, request.Date); return Ok(); } [Route("payments")] [HttpPost] public async Task InsertMultiPayment(AddMultiPaymentRequest request) { return Ok(await _ordersService.InsertMultiPayment(User.Identity.GetTenantId(), User.Identity.GetUserId(), request.OrderIds, request.Date, request.Query)); } [Route("total")] [HttpPost] public async Task GetOrdersTotal(GetOrdersTotalRequest request) { return Ok(await _ordersService.GetOrdersTotal(User.Identity.GetTenantId(), request.OrderIds, request.Query)); } [Route("setdeliverystatus")] [HttpPost] public async Task SetDeliveryStatus(SetDeliveryStatusRequest request) { var success = await _ordersService.SetDeliveryStatus(User.Identity.GetTenantId(), User.Identity.GetUserId(), request.Ids, (int)request.Status, request.Query); return Ok(new { success }); } //[Route("setpaymentstatus")] //[HttpPost] //public async Task SetPaymentStatus(SetPaymentStatusRequest request) //{ // await _ordersService.SetPaymentStatus(User.Identity.GetTenantId(), User.Identity.GetUserId(), request.Ids, (int)request.Status); // return Ok(); //} [Route("setpromisedpaymentdate")] [HttpPost] public async Task SetPromisedPaymentDate(SetDateRequest request) { await _ordersService.SetPromisedPaymentDate(User.Identity.GetTenantId(), User.Identity.GetUserId(), request.Ids, request.Date, request.Query); return Ok(); } [Route("setdeliverydate")] [HttpPost] public async Task SetDeliveryDate(SetDateRequest request) { if(!User.Identity.IsClient()) { await _ordersService.SetDeliveryDate(User.Identity.GetTenantId(), User.Identity.GetUserId(), request.Ids, request.Date, request.Query); return Ok(); } await _ordersService.SetClientDeliveryDate(User.Identity.GetTenantId(), User.Identity.GetUserId(), request.Ids, request.Date, request.Query); return Ok(); } //La fecha de pago real ahora se asigna autom�ticamente //[Route("setactualpaymentdate")] //[HttpPost] //public async Task SetActualPaymentDate(SetDateRequest request) //{ // await _ordersService.SetActualPaymentDate(User.Identity.GetTenantId(), User.Identity.GetUserId(), request.Ids, request.Date); // return Ok(); //} [Route("distinct/{propName}")] [HttpGet] public async Task GetDistinct(string propName, string q) { return Ok(await _ordersService.GetDistinctValues(User.Identity.GetTenantId(), propName, q)); } [Route("createorderfromtemplate")] [HttpPost] public async Task CreateOrderFromTemplate(Order order) //order es en realidad una plantilla { //TODO: Investigar if (User.Identity.IsClient()) { var createdOrders = await _ordersService.CreateClientOrdersFromTemplate(User.Identity.GetTenantId(), User.Identity.GetUserId(), order); foreach (var createdOrder in createdOrders) { try { var attachment = await GetOrderAsPdf(createdOrder, "/Views/Templates/Order.cshtml"); var logoUrl = $"https://{Request.Host}/api/account/logo/{createdOrder.TenantId}?t={Guid.NewGuid().ToString("N")}"; await _ordersService.SendConfirmationEmail(createdOrder, logoUrl, attachment); } catch (Exception ex) { Console.WriteLine(ex.Message); } } return Ok(); } return Ok(await _ordersService.CreateOrderFromTemplate(User.Identity.GetTenantId(), User.Identity.GetUserId(), order)); } //[AllowAnonymous] //[Route("public/getorderfromtemplate/{id}")] //[HttpGet] //public async Task GetOrderFromTemplate(int id) //{ // var newOrder = await _ordersService.GetOrderById("test", id); // var attachment = await GetOrderAsPdf(newOrder, "/Views/Templates/Order.cshtml"); // return File(attachment, "application/pdf"); //} [AllowAnonymous] [Route("public/createorderfromtemplate/{id}")] [HttpPost] public async Task CreateOrderFromPublicTemplate(string id, Order order) //order es en realidad una plantilla { if (string.IsNullOrEmpty(order.Email)) throw new BadRequestException(); var newOrder = await _ordersService.CreateOrderFromPublicTemplate(id, order); try { var attachment = await GetOrderAsPdf(newOrder, "/Views/Templates/Order.cshtml"); var logoUrl = $"https://{Request.Host}/api/account/logo/{newOrder.TenantId}?t={Guid.NewGuid().ToString("N")}"; await _ordersService.SendConfirmationEmail(newOrder, logoUrl, attachment); } catch(Exception ex) { Console.WriteLine("Error al enviar el correo " + ex.Message); } return Ok(newOrder); } //[AllowAnonymous] //[Route("createordertest")] //[HttpPost] //public async Task CreateOrder(Order order) //{ // return Ok(await _ordersService.InsertOrderTest(User.Identity.GetUserId(), order)); //} [Route("cancel")] [HttpPut] public async Task Cancel(CancelOrdersRequest request) { var logoUrl = $"https://{Request.Host}/api/account/logo/{User.Identity.GetTenantId()}?t={Guid.NewGuid().ToString("N")}"; if (User.Identity.IsClient()) await _ordersService.CancelClientOrders(User.Identity.GetTenantId(), logoUrl, User.Identity.GetUserId(), request.Ids, request.Query); else await _ordersService.CancelOrders(User.Identity.GetTenantId(), logoUrl, User.Identity.GetUserId(), request.Ids, request.Query); return Ok(); } [Route("payments/{orderPaymentId}/delete")] [HttpPut] public async Task DeleteMultiOrderPayment(int orderPaymentId) { await _ordersService.DeleteMultiOrderPayment(User.Identity.GetTenantId(), User.Identity.GetUserId(), orderPaymentId); return Ok(); } [Route("{id}/payments/{orderPaymentId}/delete")] [HttpPut] public async Task DeletePayment(int id, int orderPaymentId) { await _ordersService.DeleteOrderPayment(User.Identity.GetTenantId(), User.Identity.GetUserId(), id, orderPaymentId); return Ok(); } private static async Task RenderToStringAsync(ViewResult viewResult, IServiceProvider serviceProvider, object model = null) { if (viewResult == null) throw new ArgumentNullException(nameof(viewResult)); var httpContext = new DefaultHttpContext { RequestServices = serviceProvider }; var actionContext = new ActionContext(httpContext, new RouteData(), new ActionDescriptor()); using (var stream = new MemoryStream()) { httpContext.Response.Body = stream; // inject a convenient memory stream await viewResult.ExecuteResultAsync(actionContext); // execute view result on that stream httpContext.Response.Body.Position = 0; return new StreamReader(httpContext.Response.Body).ReadToEnd(); // collect the content of the stream } } private async Task GetOrderAsPdf(Order order, string template) { var logo = await _usersService.GetCompanyImageAsBase64String(order.TenantId, false); var view = View(template, new PrintableOrder() { Order = order, Totals = _ordersService.CalculateTotal(order), LogoImage = logo }); var htmlString = await RenderToStringAsync(view, _serviceProvider); //var converter = new HtmlToPdf(); //converter.Options.PdfPageSize = PdfPageSize.Letter; //converter.Options.PdfPageOrientation = PdfPageOrientation.Portrait; //converter.Options.MarginLeft = 15; //converter.Options.MarginRight = 15; //converter.Options.MarginTop = 15; //converter.Options.MarginBottom = 15; _generatePdf.SetConvertOptions(new ConvertOptions() { PageSize = Wkhtmltopdf.NetCore.Options.Size.Letter, PageOrientation = Wkhtmltopdf.NetCore.Options.Orientation.Portrait, PageMargins = new Wkhtmltopdf.NetCore.Options.Margins(5, 5, 5, 5) }); string baseUrl = _env.WebRootPath; //var doc = converter.ConvertHtmlString(htmlString, baseUrl); //var pdf = doc.Save(); //doc.Close(); var pdf = _generatePdf.GetPDF(htmlString); return pdf; } } public class SetLastPaymentDateRequest { public int PaymentId { get; set; } public DateTime Date { get; set; } } public class CancelOrdersRequest { public int[] Ids { get; set; } public OrdersFilterQuery Query { get; set; } } public class UpdateAccessTimeRequest { public int[] OrderIds { get; set; } } public class AddMultiPaymentRequest { public int[] OrderIds { get; set; } public DateTime Date { get; set; } public OrdersFilterQuery Query { get; set; } } public class GetOrdersTotalRequest { public int[] OrderIds { get; set; } public OrdersFilterQuery Query { get; set; } } public class AddPaymentRequest { public DateTime Date { get; set; } public decimal Amount { get; set; } } public class SetDeliveryStatusRequest { public DeliveryStatus Status { get; set; } public int[] Ids { get; set; } public OrdersFilterQuery Query { get; set; } } public class SetPaymentStatusRequest { public PaymentStatus Status { get; set; } public int[] Ids { get; set; } public OrdersFilterQuery Query { get; set; } } public class SetDateRequest { public DateTime Date { get; set; } public int[] Ids { get; set; } public OrdersFilterQuery Query { get; set; } } }