diff --git a/Nop.Plugin.Misc.AuctionPlugin/Domains/DataLayer/ProductToAuctionDbTable.cs b/Nop.Plugin.Misc.AuctionPlugin/Domains/DataLayer/ProductToAuctionDbTable.cs index a35987b..7fed99f 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Domains/DataLayer/ProductToAuctionDbTable.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Domains/DataLayer/ProductToAuctionDbTable.cs @@ -60,7 +60,7 @@ public class ProductToAuctionDbTable : MgDbTableBase productToAuction.StartingPrice = basePrice; productToAuction.CurrentPrice = basePrice; productToAuction.WinnerCustomerId = 0; - productToAuction.OrderGuid = null; + productToAuction.OrderItemId = 0; productToAuction.OrderId = 0; productToAuction.AuctionStatus = AuctionStatus.None; diff --git a/Nop.Plugin.Misc.AuctionPlugin/Domains/Entities/Interfaces/IProductToAuctionMapping.cs b/Nop.Plugin.Misc.AuctionPlugin/Domains/Entities/Interfaces/IProductToAuctionMapping.cs index e070c2d..3b81060 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Domains/Entities/Interfaces/IProductToAuctionMapping.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Domains/Entities/Interfaces/IProductToAuctionMapping.cs @@ -8,5 +8,5 @@ public interface IProductToAuctionMapping : IProductToAuctionDtoBase, ITimeStamp public int? BiddingNumber { get; set; } public int OrderId { get; set; } - public Guid? OrderGuid { get; set; } + public int OrderItemId { get; set; } } \ No newline at end of file diff --git a/Nop.Plugin.Misc.AuctionPlugin/Domains/Entities/ProductToAuctionMapping.cs b/Nop.Plugin.Misc.AuctionPlugin/Domains/Entities/ProductToAuctionMapping.cs index adcd658..38bc845 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Domains/Entities/ProductToAuctionMapping.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Domains/Entities/ProductToAuctionMapping.cs @@ -15,7 +15,7 @@ public partial class ProductToAuctionMapping : MgEntityBase, IProductToAuctionMa public int AuctionId { get; set; } public int OrderId { get; set; } - public Guid? OrderGuid { get; set; } + public int OrderItemId { get; set; } public int WinnerCustomerId { get; set; } public int? BiddingNumber { get; set; } diff --git a/Nop.Plugin.Misc.AuctionPlugin/Domains/EventConsumers/AuctionEventConsumer.cs b/Nop.Plugin.Misc.AuctionPlugin/Domains/EventConsumers/AuctionEventConsumer.cs index 2c857c2..80921ca 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Domains/EventConsumers/AuctionEventConsumer.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Domains/EventConsumers/AuctionEventConsumer.cs @@ -15,7 +15,7 @@ public class AuctionEventConsumer(IHttpContextAccessor httpContextAccessor, ILog { await Logger.InformationAsync($"AuctionEventConsumer.HandleEventAsync();"); - var productToAuctions = await ctx.ProductToAuctions.GetByProductId(eventMessage.Entity.Id).Where(x => x.AuctionStatus == AuctionStatus.None && x.OrderGuid == null).ToListAsync(); + var productToAuctions = await ctx.ProductToAuctions.GetByProductId(eventMessage.Entity.Id).Where(x => x.AuctionStatus == AuctionStatus.None && x.OrderId == 0 && x.OrderItemId == 0).ToListAsync(); foreach (var productToAuction in productToAuctions) { diff --git a/Nop.Plugin.Misc.AuctionPlugin/Hubs/SignalRMessageHandler.cs b/Nop.Plugin.Misc.AuctionPlugin/Hubs/SignalRMessageHandler.cs index eb3ff46..ea9066a 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Hubs/SignalRMessageHandler.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Hubs/SignalRMessageHandler.cs @@ -177,9 +177,9 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs productToAuction.WinnerCustomerId = lastAuctionBid.CustomerId; var placeOrderResult = await auctionService.CreateOrderForWinnerAsync(productToAuction); - if (placeOrderResult is not { Success: true }) + if (placeOrderResult == null || placeOrderResult.Id == 0) { - logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); (placeOrderResult is not {{ Success: true }})", null, customer); + logger.Error($"SignalRMessageHandler.HandleProductToAuctionStatusChangedRequest(); (placeOrderResult == null || placeOrderResult.Id == 0)", null, customer); //return; //TODO: EGYELŐRE HAGYJUK LEZÁRNI AKKOR IS, HA NEM SIKERÜLT AZ ORDERPLACE()! - J. } diff --git a/Nop.Plugin.Misc.AuctionPlugin/Services/AuctionService.cs b/Nop.Plugin.Misc.AuctionPlugin/Services/AuctionService.cs index 32fc9de..aa87929 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Services/AuctionService.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Services/AuctionService.cs @@ -11,7 +11,13 @@ using Nop.Services.Logging; using Nop.Services.Orders; using Nop.Services.Payments; using System.Linq; +using System.Xml; +using System.Xml.Serialization; using Nop.Core.Domain.Common; +using Nop.Core.Domain.Payments; +using Nop.Core.Domain.Shipping; +using Nop.Core.Domain.Stores; +using Nop.Core.Domain.Tax; using Nop.Services.Common; using Nop.Services.Customers; using Nop.Services.Shipping; @@ -26,12 +32,13 @@ public class AuctionService( AuctionDbContext ctx, IProductService productService, IWorkContext workContext, - IOrderProcessingService orderProcessingService, - IShoppingCartService shoppingCartService, + //IOrderProcessingService orderProcessingService, + //IShoppingCartService shoppingCartService, + //IPaymentService paymentService, IStoreContext storeContext, - IPaymentService paymentService, IAddressService addressService, ICustomerService customerService, + IOrderService orderService, ILogger logger) : IAuctionService { #region Methods @@ -229,7 +236,7 @@ public class AuctionService( return intoAddress; } - public async Task CreateOrderForWinnerAsync(ProductToAuctionMapping productToAuction) + public async Task CreateOrderForWinnerAsync(ProductToAuctionMapping productToAuction) { if (productToAuction is not { AuctionStatus: AuctionStatus.Sold }) { @@ -243,56 +250,53 @@ public class AuctionService( { currentCustomer = await workContext.GetCurrentCustomerAsync(); - var billingAddress = await InsertOrUpdateBillingAddressAsync(currentCustomer); + var winnerCustomer = await customerService.GetCustomerByIdAsync(productToAuction.WinnerCustomerId); + var storeId = winnerCustomer.RegisteredInStoreId; + + var billingAddress = await InsertOrUpdateBillingAddressAsync(winnerCustomer); if (billingAddress == null) { logger.Error($"AuctionService.CreateOrderForWinnerAsync(); (billingAddress == null); productToAuctionId: {productToAuction.Id}", null, currentCustomer); return null; } - var processPaymentRequest = new ProcessPaymentRequest + var customValues = new Dictionary { - PaymentMethodSystemName = "Payments.CheckMoneyOrder", - CustomerId = productToAuction.WinnerCustomerId, - OrderTotal = productToAuction.CurrentPrice, + { "PTAID", $"#{productToAuction.Id}" }, + { "AUKCIÓ", $"#{productToAuction.AuctionId}" }, + { "TÉTELSZÁM", $"#{productToAuction.SortIndex}" } }; - processPaymentRequest.CustomValues.Add("TÉTEL: ", $"#{productToAuction.SortIndex}"); - if (productToAuction.BiddingNumber != null) processPaymentRequest.CustomValues.Add("BIDNUM", $"#{productToAuction.BiddingNumber}"); - processPaymentRequest.CustomValues.Add("PTAID", $"#{productToAuction.Id}"); - var product = await productService.GetProductByIdAsync(productToAuction.ProductId); - product.DisableBuyButton = false; //TODO: ezt automatikusan kéne false-ra állítani, mikor Assign-oljuk a ProductToAuctionItem-hez! vagy valami hasonló... - J. + if (productToAuction.BiddingNumber != null) customValues.Add("BIDNUM", $"#{productToAuction.BiddingNumber}"); - var currentStore = await storeContext.GetCurrentStoreAsync(); - processPaymentRequest.StoreId = currentStore.Id; + var orderTotal = productToAuction.CurrentPrice; - await logger.InformationAsync($"AuctionService.CreateOrderForWinnerAsync(); productToAuctionId: {productToAuction.Id}; currentStoreId: {currentStore.Id}", null, currentCustomer); + var order = CreateOrder(productToAuction, orderTotal, winnerCustomer, billingAddress, storeId, customValues); + await orderService.InsertOrderAsync(order); - await paymentService.GenerateOrderGuidAsync(processPaymentRequest); - - //TODO: kitalálni melyik legyen... - J. - await shoppingCartService.ClearShoppingCartAsync(currentCustomer, currentStore.Id); - //var currentProductsInCart = await shoppingCartService.GetShoppingCartAsync(currentCustomer, ShoppingCartType.ShoppingCart, currentStore.Id, product.Id); - //if (currentProductsInCart != null) - //{ - // foreach (var shoppingCartItem in currentProductsInCart) - // await shoppingCartService.DeleteShoppingCartItemAsync(shoppingCartItem); - //} - - var cartWarnings = await shoppingCartService.AddToCartAsync(currentCustomer, product, ShoppingCartType.ShoppingCart, currentStore.Id); - if (cartWarnings.Count > 0) + if (order.Id > 0) productToAuction.OrderId = order.Id; + else { - await logger.InformationAsync($"AuctionService.CreateOrderForWinnerAsync(); cartWarnings: {string.Join("; ", cartWarnings)}", null, currentCustomer); + logger.Warning($"AuctionService.CreateOrderForWinnerAsync(); (order.Id <= 0); productToAuctionId: {productToAuction.Id}", null, currentCustomer); return null; } - var placeOrderResult = await orderProcessingService.PlaceOrderAsync(processPaymentRequest); - if (!placeOrderResult.Success) return null; + var orderItem = CreateOrderItem(productToAuction, order, orderTotal); + await orderService.InsertOrderItemAsync(orderItem); - productToAuction.OrderId = placeOrderResult.PlacedOrder.Id; - productToAuction.OrderGuid = placeOrderResult.PlacedOrder.OrderGuid; + if (orderItem.Id > 0) productToAuction.OrderItemId = orderItem.Id; + else + { + logger.Warning($"AuctionService.CreateOrderForWinnerAsync(); (orderItem.Id <= 0); productToAuctionId: {productToAuction.Id}", null, currentCustomer); + return null; + } - return placeOrderResult; + //var orderNote = CreateOrderNote(order, "..."); + //await orderService.InsertOrderNoteAsync(orderNote); + + //if (orderNote.Id <= 0) logger.Warning($"AuctionService.CreateOrderForWinnerAsync(); (orderNote.Id <= 0); productToAuctionId: {productToAuction.Id}", null, currentCustomer); //TUDATOSAN NINCS RETURN - J. + + return order; } catch (Exception ex) { @@ -302,6 +306,79 @@ public class AuctionService( return null; } + private static OrderItem CreateOrderItem(ProductToAuctionMapping productToAuction, Order order, decimal orderTotal) + { + return new OrderItem + { + ProductId = productToAuction.ProductId, + OrderId = order.Id, + OrderItemGuid = Guid.NewGuid(), + PriceExclTax = orderTotal, + PriceInclTax = orderTotal, + UnitPriceExclTax = orderTotal, + UnitPriceInclTax = orderTotal, + Quantity = productToAuction.ProductAmount, + }; + } + + private static Order CreateOrder(ProductToAuctionMapping productToAuction, decimal orderTotal, Customer customer, Address billingAddress, int storeId, Dictionary customValues) + { + return new Order + { + BillingAddressId = billingAddress.Id, + CreatedOnUtc = DateTime.UtcNow, + CurrencyRate = 1, + CustomOrderNumber = productToAuction.AuctionId + "/" + productToAuction.SortIndex, + CustomValuesXml = SerializeCustomValuesToXml(customValues), + CustomerCurrencyCode = "HUF", + CustomerId = productToAuction.WinnerCustomerId, + CustomerLanguageId = 2, + CustomerTaxDisplayType = TaxDisplayType.IncludingTax, + OrderGuid = Guid.NewGuid(), + OrderStatus = OrderStatus.Pending, + OrderTotal = orderTotal, + PaymentStatus = PaymentStatus.Pending, + PaymentMethodSystemName = "Payments.CheckMoneyOrder", + ShippingStatus = ShippingStatus.ShippingNotRequired, + StoreId = storeId, + VatNumber = customer.VatNumber, + CustomerIp = customer.LastIpAddress, + OrderSubtotalExclTax = orderTotal, + OrderSubtotalInclTax = orderTotal + }; + } + + private static OrderNote CreateOrderNote(Order order, string note) + { + return new OrderNote + { + CreatedOnUtc = order.CreatedOnUtc, + DisplayToCustomer = true, + OrderId = order.Id, + Note = note + }; + } + + private static string SerializeCustomValuesToXml(Dictionary sourceDictionary) + { + ArgumentNullException.ThrowIfNull(sourceDictionary); + + if (!sourceDictionary.Any()) + return null; + + var ds = new DictionarySerializer(sourceDictionary); + var xs = new XmlSerializer(typeof(DictionarySerializer)); + + using var textWriter = new StringWriter(); + using (var xmlWriter = XmlWriter.Create(textWriter)) + { + xs.Serialize(xmlWriter, ds); + } + + var result = textWriter.ToString(); + return result; + } + #region auctions public async Task InsertAuctionAsync(Auction auction) { diff --git a/Nop.Plugin.Misc.AuctionPlugin/Services/IAuctionService.cs b/Nop.Plugin.Misc.AuctionPlugin/Services/IAuctionService.cs index 01cd477..9c2b8a0 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Services/IAuctionService.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Services/IAuctionService.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Mvc; using Nop.Core; +using Nop.Core.Domain.Orders; using Nop.Plugin.Misc.AuctionPlugin.Domains; using Nop.Plugin.Misc.AuctionPlugin.Domains.Dtos; using Nop.Plugin.Misc.AuctionPlugin.Domains.Entities; @@ -61,5 +62,5 @@ public interface IAuctionService Task GetProductToAuctionMappingByIdAsync(int productToAuctionMappingId); Task UpdateProductToAuctionMappingAsync(ProductToAuctionMapping productToAuctionMapping); - Task CreateOrderForWinnerAsync(ProductToAuctionMapping productToAuctionMapping); + Task CreateOrderForWinnerAsync(ProductToAuctionMapping productToAuctionMapping); } \ No newline at end of file