diff --git a/Nop.Plugin.Misc.AuctionPlugin/Areas/Admin/Controllers/AnnouncementController.cs b/Nop.Plugin.Misc.AuctionPlugin/Areas/Admin/Controllers/AnnouncementController.cs index 308a04c..31d394b 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Areas/Admin/Controllers/AnnouncementController.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Areas/Admin/Controllers/AnnouncementController.cs @@ -76,7 +76,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Areas.Admin.Controllers { Title = viewModel.Name, Message = viewModel.Body, - } + }.ToJson() }; var jsonMessage = JsonConvert.SerializeObject(announcement, Formatting.Indented, new JsonSerializerSettings @@ -122,7 +122,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Areas.Admin.Controllers ProductName = viewModel.ProductName, BidPrice = viewModel.BidPrice.ToString(), NextStepAmount = viewModel.NextStepAmount.ToString() - } + }.ToJson() }; var jsonMessage = JsonConvert.SerializeObject(bid, Formatting.Indented, new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() } diff --git a/Nop.Plugin.Misc.AuctionPlugin/AuctionPlugin.cs b/Nop.Plugin.Misc.AuctionPlugin/AuctionPlugin.cs index 035a990..ad77a43 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/AuctionPlugin.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/AuctionPlugin.cs @@ -7,6 +7,7 @@ using Nop.Data; using Nop.Plugin.Misc.AuctionPlugin.Areas.Admin.Components; using Nop.Plugin.Misc.AuctionPlugin.Components; + //using Nop.Plugin.Misc.AuctionPlugin.Components; using Nop.Services.Catalog; using Nop.Services.Cms; diff --git a/Nop.Plugin.Misc.AuctionPlugin/Components/AuctionPublicViewComponent.cs b/Nop.Plugin.Misc.AuctionPlugin/Components/AuctionPublicViewComponent.cs index c041551..2adaa56 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Components/AuctionPublicViewComponent.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Components/AuctionPublicViewComponent.cs @@ -2,10 +2,12 @@ using Nop.Core; using Nop.Plugin.Misc.AuctionPlugin.Domains.Dtos; using Nop.Plugin.Misc.AuctionPlugin.Domains.Entities; +using Nop.Plugin.Misc.AuctionPlugin.Domains.Enums; using Nop.Plugin.Misc.AuctionPlugin.Models; using Nop.Plugin.Misc.AuctionPlugin.Services; using Nop.Services.Cms; using Nop.Services.Common; +using Nop.Services.Customers; using Nop.Services.Logging; using Nop.Web.Framework.Components; using Nop.Web.Framework.Infrastructure; @@ -23,6 +25,7 @@ public class AuctionPublicViewComponent : NopViewComponent protected readonly IWorkContext _workContext; protected readonly AuctionService _auctionService; protected readonly AuctionSettings _auctionSettings; + protected readonly ICustomerService _customerService; protected readonly ILogger _logger; #endregion @@ -35,6 +38,7 @@ public class AuctionPublicViewComponent : NopViewComponent IWorkContext workContext, AuctionService auctionService, AuctionSettings auctionSettings, + ICustomerService customerService, ILogger logger) { _addressService = addressService; @@ -43,6 +47,7 @@ public class AuctionPublicViewComponent : NopViewComponent _workContext = workContext; _auctionService = auctionService; _auctionSettings = auctionSettings; + _customerService = customerService; _logger = logger; } @@ -100,6 +105,7 @@ public class AuctionPublicViewComponent : NopViewComponent List auctionIds = await _auctionService.GetProductToAuctionsByProductIdAsync(productDetailsModel.Id); int auctionId = 0; + AuctionDto auction; if(auctionIds == null || auctionIds.Count == 0) { return Content(string.Empty); @@ -112,27 +118,32 @@ public class AuctionPublicViewComponent : NopViewComponent //we have more auctions so we return the closest open foreach (var auctionMapping in auctionIds) { - var auction = await _auctionService.GetAuctionDtoByIdAsync(auctionMapping.AuctionId); - if (!auction.Closed) + var auctionItem = await _auctionService.GetAuctionDtoByIdAsync(auctionMapping.AuctionId); + if (!auctionItem.Closed) { - openAuctionList.Add(auction); + openAuctionList.Add(auctionItem); } } //first auction that started or strats not earlier than yesterday - auctionId = openAuctionList.Where(x => x.StartDateUtc > DateTime.UtcNow.AddDays(-1)).OrderBy(x => x.StartDateUtc).FirstOrDefault().Id; + auction = openAuctionList.Where(x => x.StartDateUtc > DateTime.UtcNow.AddDays(-1)).OrderBy(x => x.StartDateUtc).FirstOrDefault(); + auctionId = auction.Id; } else { - var valami = await _auctionService.GetAuctionDtoByIdAsync(auctionIds.FirstOrDefault().AuctionId); - auctionId = valami.Id; + auction = await _auctionService.GetAuctionDtoByIdAsync(auctionIds.FirstOrDefault().AuctionId); + auctionId = auction.Id; + } var productToAuctionId = await _auctionService.GetProductToAuctionByAuctionIdAndProductIdAsync(auctionId, productDetailsModel.Id); + productBidBoxViewModel.IsAdmin = await _customerService.IsAdminAsync(customer); + productBidBoxViewModel.IsGuest = await _customerService.IsGuestAsync(customer); + productBidBoxViewModel.AuctionClosed = auction.Closed; productBidBoxViewModel.WidgetZone = widgetZone; productBidBoxViewModel.BasePrice = productDetailsModel.ProductPrice.OldPriceValue; productBidBoxViewModel.CurrentPrice = productDetailsModel.ProductPrice.PriceValue; - productBidBoxViewModel.ProductToAuctionId = productToAuctionId.FirstOrDefault().Id; + productBidBoxViewModel.ProductToAuctionsId = productToAuctionId.FirstOrDefault().Id; productBidBoxViewModel.AuctionId = auctionId; productBidBoxViewModel.CustomerId = customer.Id; productBidBoxViewModel.ProductId = productDetailsModel.Id; diff --git a/Nop.Plugin.Misc.AuctionPlugin/Content/Js/LiveAnnouncement.js b/Nop.Plugin.Misc.AuctionPlugin/Content/Js/LiveAnnouncement.js index 40a3eef..d69590f 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Content/Js/LiveAnnouncement.js +++ b/Nop.Plugin.Misc.AuctionPlugin/Content/Js/LiveAnnouncement.js @@ -24,9 +24,10 @@ $(function () { start(); }); - window.sendMessageToServer = function (messageType, data) { + window.sendMessageToServer = function (messageType, senderId, data) { var messageWrapper = { MessageType: messageType, + SenderId: senderId, Data: data }; diff --git a/Nop.Plugin.Misc.AuctionPlugin/Content/Js/MgMessageHandler.js b/Nop.Plugin.Misc.AuctionPlugin/Content/Js/MgMessageHandler.js index bf6c458..5fec22e 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Content/Js/MgMessageHandler.js +++ b/Nop.Plugin.Misc.AuctionPlugin/Content/Js/MgMessageHandler.js @@ -3,7 +3,8 @@ let animation = "slideDown"; const handlers = { announcement: function (data) { - toastr.info(`
${data.message}
`, data.title, { + var myObject = JSON.parse(data); + toastr.info(`
${myObject.message}
`, myObject.title, { "closeButton": true, "positionClass": "toast-bottom-right", "newestOnTop": true, @@ -22,7 +23,9 @@ $('.toast-info').css("background-color", "#008080"); }, bidNotification: function (data) { - toastr.success(`

${data.bidPrice}

${data.productName}

`, "New bid arrived", { + console.log(data); + var myObject = JSON.parse(data); + toastr.success(`

${myObject.bidPrice}

${myObject.productName}

`, "New bid arrived", { "closeButton": true, "positionClass": "toast-bottom-right", "newestOnTop": true, @@ -43,39 +46,36 @@ var publicProductBidBox = document.getElementById("publicProductBidBox"); if (publicProductBidBox) { - refreshPublicBidBox(data); + refreshPublicBidBox(myObject); } }, - auctionUpdateAlternate: function (data) { - const widgetPriceElement = document.getElementById("WidgetPrice"); - - if (widgetPriceElement) { - widgetPriceElement.textContent = data.bidPrice; // Update the price - console.log(`WidgetPrice updated to: ${data.bidPrice}`); - } else { - console.warn("Element with ID 'WidgetPrice' not found in the DOM."); + openItemMessage: function (data) { + var myObject = JSON.parse(data); + toastr.success(`

${myObject.bidPrice}

${myObject.productName}

`, "Item auction is OPENED!", { + "closeButton": true, + "positionClass": "toast-bottom-right", + "newestOnTop": true, + "progressBar": true, + "preventDuplicates": false, + "onclick": null, + "showDuration": "30000", + "hideDuration": "1000", + "timeOut": "5000", + "extendedTimeOut": "1000", + "showEasing": "swing", + "hideEasing": "linear", + "showMethod": animation, + "hideMethod": "fadeOut" + }); + $('.toast-success').css("background-color", "#4caf50"); + + var publicProductBidBox = document.getElementById("publicProductBidBox"); + if (publicProductBidBox) { + refreshPublicBidBox(myObject); } + }, - //auctionUpdate: function (data) { - // // Refresh the ViewComponent using AJAX - // $.ajax({ - // url: '/Auction/RefreshAuctionWidget', // Controller endpoint - // type: 'POST', - // contentType: 'application/json', - // data: JSON.stringify({ - // WidgetZone: data.WidgetZone, - // ProductId: data.ProductId - // }), - // success: function (response) { - // //$('#auction-widget').html(response); // Update the DOM element - // console.log("Auction widget refreshed!"); - // }, - // error: function (error) { - // console.error("Error refreshing auction widget:", error); - // } - // }); - //}, // Add more handlers as needed default: function (data) { @@ -87,10 +87,13 @@ function messageRouter(message) { // Parse the JSON message try { - const parsedMessage = JSON.parse(message); - const messageType = parsedMessage.messageType; - const messageData = parsedMessage.data; + var parsedMessage = JSON.parse(message); + var messageType = parsedMessage.messageType; + var senderId = parsedMessage.senderId; + var messageData = parsedMessage.data; console.log("Message type:" + messageType); + console.log("Message sender:" + senderId); + console.log("Message content" + parsedMessage.data); // Route to appropriate handler, default if no match (handlers[messageType] || handlers.default)(messageData); } catch (e) { diff --git a/Nop.Plugin.Misc.AuctionPlugin/Models/AuctionBidRequest.cs b/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/AuctionBidRequest.cs similarity index 100% rename from Nop.Plugin.Misc.AuctionPlugin/Models/AuctionBidRequest.cs rename to Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/AuctionBidRequest.cs diff --git a/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/MessageWrapper.cs b/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/MessageWrapper.cs index a081d82..3ee0eb2 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/MessageWrapper.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/MessageWrapper.cs @@ -9,6 +9,7 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs.Messages public class MessageWrapper { public string MessageType { get; set; } - public object Data { get; set; } + public int SenderId { get; set; } + public string Data { get; set; } } } diff --git a/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/OpenItemRequest.cs b/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/OpenItemRequest.cs new file mode 100644 index 0000000..d62e82d --- /dev/null +++ b/Nop.Plugin.Misc.AuctionPlugin/Hubs/Messages/OpenItemRequest.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Nop.Plugin.Misc.AuctionPlugin.Domains.Dtos; + +namespace Nop.Plugin.Misc.AuctionPlugin.Models +{ + public class OpenItemRequest : AuctionBidDto + { + + } +} diff --git a/Nop.Plugin.Misc.AuctionPlugin/Hubs/SignalRMessageHandler.cs b/Nop.Plugin.Misc.AuctionPlugin/Hubs/SignalRMessageHandler.cs index 7445cf9..faf8f2f 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Hubs/SignalRMessageHandler.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Hubs/SignalRMessageHandler.cs @@ -52,7 +52,11 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs switch (message.MessageType) { case "BidRequestMessage": - await HandleBidRequest(message.Data.ToString()?.JsonTo()); + await HandleBidRequest(message.SenderId, message.Data.JsonTo()); + break; + + case "OpenItemRequestMessage": + await HandleOpenItemMessageRequest(message.SenderId, message.Data.JsonTo()); break; // Add other message types here @@ -62,7 +66,37 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs } } - private async Task HandleBidRequest(AuctionBidRequest bidRequestMessage) + private async Task HandleOpenItemMessageRequest(int SenderId, OpenItemRequest openItemMessage) + { + if (openItemMessage == null) + { + _logger.Error($"SignalRMessageHandler.HandleOpenItemMessageRequest(); openItemRequestMessage == null"); + return; + } + + try + { + await _logger.InformationAsync($"SignalRMessageHandler.HandleOpenItemMessageRequest(); Item to open: - ProductToAuctionMappingId: {openItemMessage.ProductAuctionMappingId}"); + + //get auction + var auction = await _auctionService.GetAuctionDtoByProductToAuctionIdAsync(openItemMessage.ProductAuctionMappingId); + //get productToAuction + var productToAuction = await _auctionService.GetProductToAuctionDtoByIdAsync(openItemMessage.ProductAuctionMappingId); + + auction.Closed = false; + + await _logger.InformationAsync($"SignalRMessageHandler.HandleOpenItemMessageRequest(); Auction {auction.Id}, ProducToAuction {productToAuction.Id}"); + //_auctionService.UpdateAuctionAsync(auction); + + } + catch (Exception ex) + { + _logger.Error($"Error {ex.Message}"); + } + + } + + private async Task HandleBidRequest(int senderId, AuctionBidRequest bidRequestMessage) { if (bidRequestMessage == null) { @@ -128,12 +162,13 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Hubs var bid = new MessageWrapper { MessageType = "bidNotification", + SenderId = senderId, Data = new BidNotificationMessage(await _auctionService.GetAuctionDtoWithProductByIdAsync(auction.Id, activeProductAuction.ProductId, true)) { ProductName = auctionBid.ProductId.ToString(), BidPrice = auctionBid.BidPrice.ToString(CultureInfo.InvariantCulture), NextStepAmount = "50000" - } + }.ToJson() }; await _hubContext.Clients.All.SendAsync("send", bid.ToJson()); diff --git a/Nop.Plugin.Misc.AuctionPlugin/Models/ProductBidBoxViewModel.cs b/Nop.Plugin.Misc.AuctionPlugin/Models/ProductBidBoxViewModel.cs index 47e68e2..3707101 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Models/ProductBidBoxViewModel.cs +++ b/Nop.Plugin.Misc.AuctionPlugin/Models/ProductBidBoxViewModel.cs @@ -1,4 +1,5 @@ -using Nop.Web.Framework.Models; +using Nop.Plugin.Misc.AuctionPlugin.Domains.Enums; +using Nop.Web.Framework.Models; using System; using System.Collections.Generic; using System.Linq; @@ -9,8 +10,11 @@ namespace Nop.Plugin.Misc.AuctionPlugin.Models { public record ProductBidBoxViewModel: BaseNopModel { - public int ProductToAuctionId { get; set; } + public int ProductToAuctionsId { get; set; } + public bool IsAdmin { get; set; } + public bool IsGuest { get; set; } public int AuctionId { get; set; } + public bool AuctionClosed { get; set; } public int ProductId { get; set; } public int CustomerId { get; set; } diff --git a/Nop.Plugin.Misc.AuctionPlugin/Views/PublicProductBidBox.cshtml b/Nop.Plugin.Misc.AuctionPlugin/Views/PublicProductBidBox.cshtml index d674954..91b0d75 100644 --- a/Nop.Plugin.Misc.AuctionPlugin/Views/PublicProductBidBox.cshtml +++ b/Nop.Plugin.Misc.AuctionPlugin/Views/PublicProductBidBox.cshtml @@ -3,41 +3,76 @@ @* @Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(myObj) as String) *@ - -
+@{ + if (!Model.IsGuest) + { +
+

This item is under auction!

+
+
+ Base Price: + + @String.Format("{0:c}", Model.BasePrice) + @* @(decimal?.Round(Model.BasePrice, 2, MidpointRounding.AwayFromZero)) *@ + +
+
+ Bid Step: + @String.Format("{0:c}", Model.LicitStep) +
+
+ + @* - @* *@ -
-
- +
+
- @* *@ -
- +
+ + + + if (Model.IsAdmin) + { +
+

Manage auction!

+
+ + +
+
+ } + else + { +

No access to admin level buttons

+ } + + + } + else + { +
+

This item is under auction!

+
+ +

Please log in or register to participate!

+
+
+ } +}