Compare commits
2 Commits
e03a9cf6db
...
7d82c86261
| Author | SHA1 | Date |
|---|---|---|
|
|
7d82c86261 | |
|
|
566ff1ea5f |
|
|
@ -1,21 +1,21 @@
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Nop.Plugin.Misc.AIPlugin.Areas.Admin.Models;
|
using Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Models;
|
||||||
using Nop.Plugin.Misc.AIPlugin;
|
using Nop.Plugin.Misc.FruitBankPlugin;
|
||||||
//using Nop.Plugin.Misc.AIPlugin;
|
//using Nop.Plugin.Misc.FruitBankPlugin;
|
||||||
using Nop.Services.Configuration;
|
using Nop.Services.Configuration;
|
||||||
using Nop.Web.Framework.Controllers;
|
using Nop.Web.Framework.Controllers;
|
||||||
using Nop.Services.Messages;
|
using Nop.Services.Messages;
|
||||||
|
|
||||||
namespace Nop.Plugin.Misc.AIPlugin.Controllers
|
namespace Nop.Plugin.Misc.FruitBankPlugin.Controllers
|
||||||
{
|
{
|
||||||
[Area("Admin")]
|
[Area("Admin")]
|
||||||
public class AIPluginAdminController : BasePluginController
|
public class FruitBankPluginAdminController : BasePluginController
|
||||||
{
|
{
|
||||||
private readonly INotificationService _notificationService;
|
private readonly INotificationService _notificationService;
|
||||||
private readonly ISettingService _settingService;
|
private readonly ISettingService _settingService;
|
||||||
private readonly OpenAiSettings _settings;
|
private readonly OpenAiSettings _settings;
|
||||||
|
|
||||||
public AIPluginAdminController(INotificationService notificationService, ISettingService settingService, OpenAiSettings settings)
|
public FruitBankPluginAdminController(INotificationService notificationService, ISettingService settingService, OpenAiSettings settings)
|
||||||
{
|
{
|
||||||
_notificationService = notificationService;
|
_notificationService = notificationService;
|
||||||
_settingService = settingService;
|
_settingService = settingService;
|
||||||
|
|
@ -29,7 +29,7 @@ namespace Nop.Plugin.Misc.AIPlugin.Controllers
|
||||||
{
|
{
|
||||||
ApiKey = _settings.ApiKey
|
ApiKey = _settings.ApiKey
|
||||||
};
|
};
|
||||||
return View("~/Plugins/Misc.AIPlugin/Views/Configure/Configure.cshtml", model);
|
return View("~/Plugins/Misc.FruitBankPlugin/Areas/Admin/Views/Configure/Configure.cshtml", model);
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpPost]
|
[HttpPost]
|
||||||
|
|
@ -5,11 +5,11 @@ using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Nop.Plugin.Misc.AIPlugin.Areas.Admin.Models
|
namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Models
|
||||||
{
|
{
|
||||||
public record ConfigureModel
|
public record ConfigureModel
|
||||||
{
|
{
|
||||||
[NopResourceDisplayName("Plugins.AIPlugin.Fields.ApiKey")]
|
[NopResourceDisplayName("Plugins.FruitBankPlugin.Fields.ApiKey")]
|
||||||
public string ApiKey { get; set; }
|
public string ApiKey { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
@model Nop.Plugin.Misc.AIPlugin.Models.ConfigureModel
|
@model Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Models.ConfigureModel
|
||||||
|
|
||||||
@{
|
@{
|
||||||
Layout = "_AdminLayout";
|
Layout = "_AdminLayout";
|
||||||
Html.SetActiveMenuItemSystemName("AiAssistant.Configure");
|
NopHtml.SetActiveMenuItemSystemName("AiAssistant.Configure");
|
||||||
}
|
}
|
||||||
|
|
||||||
<div class="card">
|
<div class="card">
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||||
@addTagHelper *, Nop.Web.Framework
|
@addTagHelper *, Nop.Web.Framework
|
||||||
|
|
||||||
|
@inject INopHtmlHelper NopHtml
|
||||||
|
|
||||||
@using Microsoft.AspNetCore.Mvc.ViewFeatures
|
@using Microsoft.AspNetCore.Mvc.ViewFeatures
|
||||||
@using Nop.Web.Framework.UI
|
@using Nop.Web.Framework.UI
|
||||||
@using Nop.Web.Framework.Extensions
|
@using Nop.Web.Framework.Extensions
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Nop.Web.Framework.Components;
|
using Nop.Web.Framework.Components;
|
||||||
|
|
||||||
namespace Nop.Plugin.Misc.AIPlugin.Components;
|
namespace Nop.Plugin.Misc.FruitBankPlugin.Components;
|
||||||
|
|
||||||
[ViewComponent(Name = "Custom")]
|
[ViewComponent(Name = "Custom")]
|
||||||
public class CustomViewComponent : NopViewComponent
|
public class CustomViewComponent : NopViewComponent
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ using System.Linq;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Nop.Plugin.Misc.AIPlugin.Components
|
namespace Nop.Plugin.Misc.FruitBankPlugin.Components
|
||||||
{
|
{
|
||||||
|
|
||||||
[ViewComponent(Name = "ProductAIWidget")]
|
[ViewComponent(Name = "ProductAIWidget")]
|
||||||
|
|
@ -20,7 +20,7 @@ namespace Nop.Plugin.Misc.AIPlugin.Components
|
||||||
|
|
||||||
if (product == null)
|
if (product == null)
|
||||||
return Content(""); // ne rendereljen semmit, ha nincs product
|
return Content(""); // ne rendereljen semmit, ha nincs product
|
||||||
return View("~/Plugins/Misc.AIPlugin/Views/ProductAIListWidget.cshtml", product);
|
return View("~/Plugins/Misc.FruitBankPlugin/Views/ProductAIListWidget.cshtml", product);
|
||||||
}
|
}
|
||||||
else if (additionalData is Nop.Web.Models.Catalog.ProductDetailsModel)
|
else if (additionalData is Nop.Web.Models.Catalog.ProductDetailsModel)
|
||||||
{
|
{
|
||||||
|
|
@ -28,7 +28,7 @@ namespace Nop.Plugin.Misc.AIPlugin.Components
|
||||||
|
|
||||||
if (product == null)
|
if (product == null)
|
||||||
return Content(""); // ne rendereljen semmit, ha nincs product
|
return Content(""); // ne rendereljen semmit, ha nincs product
|
||||||
return View("~/Plugins/Misc.AIPlugin/Views/ProductAIWidget.cshtml", product);
|
return View("~/Plugins/Misc.FruitBankPlugin/Views/ProductAIWidget.cshtml", product);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return Content(""); // ne rendereljen semmit, ha nem productDetailModel vagy productOverviewModel
|
return Content(""); // ne rendereljen semmit, ha nem productDetailModel vagy productOverviewModel
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
|
namespace Nop.Plugin.Misc.FruitBankPlugin.Controllers
|
||||||
|
{
|
||||||
|
[Area("Admin")] // ha admin oldalra, de a frontendre ne legyen
|
||||||
|
public class CheckoutController : Controller
|
||||||
|
{
|
||||||
|
[Route("checkout/pending-measurement")]
|
||||||
|
public IActionResult PendingMeasurementWarning()
|
||||||
|
{
|
||||||
|
// visszaadja a view-t
|
||||||
|
return View("~/Plugins/Misc.FruitBankPlugin/Views/Checkout/PendingMeasurementWarning.cshtml");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
using Nop.Core;
|
using Nop.Core;
|
||||||
|
|
||||||
namespace Nop.Plugin.Misc.AIPlugin.Domains;
|
namespace Nop.Plugin.Misc.FruitBankPlugin.Domains;
|
||||||
|
|
||||||
public partial class CustomTable : BaseEntity
|
public partial class CustomTable : BaseEntity
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,55 @@
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.AspNetCore.Mvc.Filters;
|
||||||
|
using Nop.Core.Domain.Orders;
|
||||||
|
using Nop.Services.Orders;
|
||||||
|
using Nop.Services.Common;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Nop.Core;
|
||||||
|
using Nop.Plugin.Misc.FruitBankPlugin.Services;
|
||||||
|
|
||||||
|
namespace Nop.Plugin.Misc.FruitBankPlugin.Filters
|
||||||
|
{
|
||||||
|
public class PendingMeasurementCheckoutFilter : IAsyncActionFilter
|
||||||
|
{
|
||||||
|
private readonly IWorkContext _workContext;
|
||||||
|
private readonly IOrderService _orderService;
|
||||||
|
private readonly IOrderMeasurementService _orderMeasurementService;
|
||||||
|
|
||||||
|
public PendingMeasurementCheckoutFilter(
|
||||||
|
IWorkContext workContext,
|
||||||
|
IOrderService orderService,
|
||||||
|
IOrderMeasurementService orderMeasurementService)
|
||||||
|
{
|
||||||
|
_workContext = workContext;
|
||||||
|
_orderService = orderService;
|
||||||
|
_orderMeasurementService = orderMeasurementService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
|
||||||
|
{
|
||||||
|
// csak a ConfirmOrder action-nál kell ellenőrizni
|
||||||
|
var actionName = context.ActionDescriptor.RouteValues["action"];
|
||||||
|
var controllerName = context.ActionDescriptor.RouteValues["controller"];
|
||||||
|
|
||||||
|
if (controllerName == "Checkout" && actionName == "ConfirmOrder")
|
||||||
|
{
|
||||||
|
// lekérjük a user aktuális kosarát
|
||||||
|
var customer = await _workContext.GetCurrentCustomerAsync();
|
||||||
|
var order = await _orderService.GetOrderByIdAsync((int)context.ActionArguments["orderId"]); // ha van orderId param
|
||||||
|
|
||||||
|
if (order != null && await _orderMeasurementService.IsPendingMeasurementAsync(order))
|
||||||
|
{
|
||||||
|
context.Result = new RedirectToRouteResult(new
|
||||||
|
{
|
||||||
|
controller = "Checkout",
|
||||||
|
action = "PendingMeasurementWarning"
|
||||||
|
});
|
||||||
|
return; // itt kilépünk, a fizetés nem engedélyezett
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await next(); // mehet a többi pipeline
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,14 @@
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Nop.Plugin.Misc.FruitBankPlugin
|
||||||
|
{
|
||||||
|
public static class FruitBankConsts
|
||||||
|
{
|
||||||
|
public const string RequiresMeasurementAttr = "PriceByMeasurement.RequiresMeasurement";
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
using Microsoft.AspNetCore.Mvc.Infrastructure;
|
||||||
using Microsoft.AspNetCore.Mvc.Routing;
|
using Microsoft.AspNetCore.Mvc.Routing;
|
||||||
using Nop.Plugin.Misc.AIPlugin.Components;
|
using Nop.Plugin.Misc.FruitBankPlugin.Components;
|
||||||
using Nop.Services.Cms;
|
using Nop.Services.Cms;
|
||||||
using Nop.Services.Configuration;
|
using Nop.Services.Configuration;
|
||||||
using Nop.Services.Localization;
|
using Nop.Services.Localization;
|
||||||
|
|
@ -12,12 +12,12 @@ using Nop.Web.Framework.Infrastructure;
|
||||||
using Nop.Web.Framework.Menu;
|
using Nop.Web.Framework.Menu;
|
||||||
|
|
||||||
|
|
||||||
namespace Nop.Plugin.Misc.AIPlugin
|
namespace Nop.Plugin.Misc.FruitBankPlugin
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Main plugin class
|
/// Main plugin class
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class AIPlugin : BasePlugin, IWidgetPlugin
|
public class FruitBankPlugin : BasePlugin, IWidgetPlugin
|
||||||
{
|
{
|
||||||
protected readonly IActionContextAccessor _actionContextAccessor;
|
protected readonly IActionContextAccessor _actionContextAccessor;
|
||||||
private readonly ISettingService _settingService;
|
private readonly ISettingService _settingService;
|
||||||
|
|
@ -30,7 +30,7 @@ namespace Nop.Plugin.Misc.AIPlugin
|
||||||
//handle AdminMenuCreatedEvent
|
//handle AdminMenuCreatedEvent
|
||||||
|
|
||||||
|
|
||||||
public AIPlugin(IActionContextAccessor actionContextAccessor,
|
public FruitBankPlugin(IActionContextAccessor actionContextAccessor,
|
||||||
ISettingService settingService,
|
ISettingService settingService,
|
||||||
//IWebHelper webHelper,
|
//IWebHelper webHelper,
|
||||||
ILocalizationService localizationService,
|
ILocalizationService localizationService,
|
||||||
|
|
@ -50,6 +50,9 @@ namespace Nop.Plugin.Misc.AIPlugin
|
||||||
// --- INSTALL ---
|
// --- INSTALL ---
|
||||||
public override async Task InstallAsync()
|
public override async Task InstallAsync()
|
||||||
{
|
{
|
||||||
|
|
||||||
|
// TODO: Add "NeedsToBeMeasured" product attribute if not exists
|
||||||
|
|
||||||
// Default settings
|
// Default settings
|
||||||
var settings = new OpenAiSettings
|
var settings = new OpenAiSettings
|
||||||
{
|
{
|
||||||
|
|
@ -88,9 +91,9 @@ namespace Nop.Plugin.Misc.AIPlugin
|
||||||
|
|
||||||
// var pluginNode = new AdminMenuItem
|
// var pluginNode = new AdminMenuItem
|
||||||
// {
|
// {
|
||||||
// SystemName = "AIPlugin.Configure",
|
// SystemName = "FruitBankPlugin.Configure",
|
||||||
// Title = "AI Assistant",
|
// Title = "AI Assistant",
|
||||||
// Url = $"{_webHelper.GetStoreLocation()}Admin/AIPluginAdmin/Configure",
|
// Url = $"{_webHelper.GetStoreLocation()}Admin/FruitBankPluginAdmin/Configure",
|
||||||
// Visible = true
|
// Visible = true
|
||||||
// };
|
// };
|
||||||
// rootNode.ChildNodes.Add(pluginNode);
|
// rootNode.ChildNodes.Add(pluginNode);
|
||||||
|
|
@ -128,15 +131,15 @@ namespace Nop.Plugin.Misc.AIPlugin
|
||||||
{
|
{
|
||||||
new()
|
new()
|
||||||
{
|
{
|
||||||
// SystemName = "AIPlugin.Configure",
|
// SystemName = "FruitBankPlugin.Configure",
|
||||||
// Title = "AI Assistant",
|
// Title = "AI Assistant",
|
||||||
// Url = $"{_webHelper.GetStoreLocation()}Admin/AIPluginAdmin/Configure",
|
// Url = $"{_webHelper.GetStoreLocation()}Admin/FruitBankPluginAdmin/Configure",
|
||||||
// Visible = true
|
// Visible = true
|
||||||
Visible = true,
|
Visible = true,
|
||||||
SystemName = PluginDescriptor.SystemName,
|
SystemName = PluginDescriptor.SystemName,
|
||||||
Title = PluginDescriptor.FriendlyName,
|
Title = PluginDescriptor.FriendlyName,
|
||||||
IconClass = "far fa-circle",
|
IconClass = "far fa-circle",
|
||||||
Url = _adminMenu.GetMenuItemUrl("AIPlugin", "Configure"),
|
Url = _adminMenu.GetMenuItemUrl("FruitBankPlugin", "Configure"),
|
||||||
//Url = "Admin/SignalRApi/Configure",
|
//Url = "Admin/SignalRApi/Configure",
|
||||||
//ControllerName = "SignalRApi",
|
//ControllerName = "SignalRApi",
|
||||||
//ActionName = "Configure",
|
//ActionName = "Configure",
|
||||||
|
|
@ -148,7 +151,7 @@ namespace Nop.Plugin.Misc.AIPlugin
|
||||||
|
|
||||||
public override string GetConfigurationPageUrl()
|
public override string GetConfigurationPageUrl()
|
||||||
{
|
{
|
||||||
return _urlHelperFactory.GetUrlHelper(_actionContextAccessor.ActionContext).RouteUrl("Plugin.Misc.AIPlugin.Configure");
|
return _urlHelperFactory.GetUrlHelper(_actionContextAccessor.ActionContext).RouteUrl("Plugin.Misc.FruitBankPlugin.Configure");
|
||||||
}
|
}
|
||||||
|
|
||||||
public Type GetWidgetViewComponent(string widgetZone)
|
public Type GetWidgetViewComponent(string widgetZone)
|
||||||
|
|
@ -1,10 +1,14 @@
|
||||||
using Microsoft.AspNetCore.Builder;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Microsoft.AspNetCore.Mvc.Razor;
|
using Microsoft.AspNetCore.Mvc.Razor;
|
||||||
|
using Microsoft.AspNetCore.SignalR;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Nop.Core.Infrastructure;
|
using Nop.Core.Infrastructure;
|
||||||
|
using Nop.Plugin.Misc.FruitBankPlugin.Filters;
|
||||||
|
using Nop.Plugin.Misc.FruitBankPlugin.Services;
|
||||||
|
using Nop.Services.Catalog;
|
||||||
|
|
||||||
namespace Nop.Plugin.Misc.AIPlugin.Infrastructure;
|
namespace Nop.Plugin.Misc.FruitBankPlugin.Infrastructure;
|
||||||
|
|
||||||
public class PluginNopStartup : INopStartup
|
public class PluginNopStartup : INopStartup
|
||||||
{
|
{
|
||||||
|
|
@ -20,8 +24,28 @@ public class PluginNopStartup : INopStartup
|
||||||
options.ViewLocationExpanders.Add(new ViewLocationExpander());
|
options.ViewLocationExpanders.Add(new ViewLocationExpander());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
services.AddCors(feature =>
|
||||||
|
feature.AddPolicy(
|
||||||
|
"AllowBlazorClient",
|
||||||
|
apiPolicy => apiPolicy
|
||||||
|
.WithOrigins("https://localhost:7144")
|
||||||
|
.AllowAnyHeader()
|
||||||
|
.AllowAnyMethod()
|
||||||
|
.AllowCredentials()
|
||||||
|
));
|
||||||
|
|
||||||
|
services.AddSignalR();
|
||||||
|
|
||||||
//register services and interfaces
|
//register services and interfaces
|
||||||
//services.AddScoped<CustomModelFactory, ICustomerModelFactory>();
|
//services.AddScoped<CustomModelFactory, ICustomerModelFactory>();
|
||||||
|
services.AddScoped<IPriceCalculationService, CustomPriceCalculationService>();
|
||||||
|
services.AddScoped<PriceCalculationService, CustomPriceCalculationService>();
|
||||||
|
services.AddScoped<IOrderMeasurementService, OrderMeasurementService>();
|
||||||
|
services.AddScoped<PendingMeasurementCheckoutFilter>();
|
||||||
|
services.AddControllersWithViews(options =>
|
||||||
|
{
|
||||||
|
options.Filters.AddService<PendingMeasurementCheckoutFilter>();
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -30,10 +54,24 @@ public class PluginNopStartup : INopStartup
|
||||||
/// <param name="application">Builder for configuring an application's request pipeline</param>
|
/// <param name="application">Builder for configuring an application's request pipeline</param>
|
||||||
public void Configure(IApplicationBuilder application)
|
public void Configure(IApplicationBuilder application)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
application.UseWhen(context => context.Request.Path.StartsWithSegments("/fbhub"), app =>
|
||||||
|
{
|
||||||
|
app.UseCors("AllowBlazorClient");
|
||||||
|
app.UseRouting();
|
||||||
|
app.UseEndpoints(endpoints =>
|
||||||
|
{
|
||||||
|
endpoints.MapHub<FruitBankHub>("/fbhub");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets order of this startup configuration implementation
|
/// Gets order of this startup configuration implementation
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int Order => 3000;
|
public int Order => 4000;
|
||||||
}
|
}
|
||||||
|
|
@ -1,7 +1,10 @@
|
||||||
using Microsoft.AspNetCore.Routing;
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Routing;
|
||||||
|
using Nop.Plugin.Misc.FruitBankPlugin.Services;
|
||||||
|
using Nop.Web.Framework;
|
||||||
using Nop.Web.Framework.Mvc.Routing;
|
using Nop.Web.Framework.Mvc.Routing;
|
||||||
|
|
||||||
namespace Nop.Plugin.Misc.AIPlugin.Infrastructure;
|
namespace Nop.Plugin.Misc.FruitBankPlugin.Infrastructure;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Represents plugin route provider
|
/// Represents plugin route provider
|
||||||
|
|
@ -14,7 +17,11 @@ public class RouteProvider : IRouteProvider
|
||||||
/// <param name="endpointRouteBuilder">Route builder</param>
|
/// <param name="endpointRouteBuilder">Route builder</param>
|
||||||
public void RegisterRoutes(IEndpointRouteBuilder endpointRouteBuilder)
|
public void RegisterRoutes(IEndpointRouteBuilder endpointRouteBuilder)
|
||||||
{
|
{
|
||||||
|
endpointRouteBuilder.MapControllerRoute(name: "Plugin.Misc.FruitBankPlugin.Configure",
|
||||||
|
pattern: "Admin/FruitBankPlugin/Configure",
|
||||||
|
defaults: new { controller = "FruitBankPluginAdmin", action = "Configure", area = AreaNames.ADMIN });
|
||||||
|
|
||||||
|
//endpointRouteBuilder.MapHub<FruitBankHub>("/fbhub");//.RequireCors("AllowBlazorClient");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
using Microsoft.AspNetCore.Mvc.Razor;
|
using Microsoft.AspNetCore.Mvc.Razor;
|
||||||
|
|
||||||
namespace Nop.Plugin.Misc.AIPlugin.Infrastructure;
|
namespace Nop.Plugin.Misc.FruitBankPlugin.Infrastructure;
|
||||||
|
|
||||||
public class ViewLocationExpander : IViewLocationExpander
|
public class ViewLocationExpander : IViewLocationExpander
|
||||||
{
|
{
|
||||||
|
|
@ -26,11 +26,11 @@ public class ViewLocationExpander : IViewLocationExpander
|
||||||
{
|
{
|
||||||
if (context.AreaName == "Admin")
|
if (context.AreaName == "Admin")
|
||||||
{
|
{
|
||||||
viewLocations = new[] { $"/Plugins/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Views/{context.ControllerName}/{context.ViewName}.cshtml" }.Concat(viewLocations);
|
viewLocations = new[] { $"/Plugins/Nop.Plugin.Misc.FruitBankPlugin/Areas/Admin/Views/{context.ControllerName}/{context.ViewName}.cshtml" }.Concat(viewLocations);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
viewLocations = new[] { $"/Plugins/Nop.Plugin.Misc.AIPlugin/Views/{context.ControllerName}/{context.ViewName}.cshtml" }.Concat(viewLocations);
|
viewLocations = new[] { $"/Plugins/Nop.Plugin.Misc.FruitBankPlugin/Views/{context.ControllerName}/{context.ViewName}.cshtml" }.Concat(viewLocations);
|
||||||
}
|
}
|
||||||
|
|
||||||
return viewLocations;
|
return viewLocations;
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
using FluentMigrator.Builders.Create.Table;
|
using FluentMigrator.Builders.Create.Table;
|
||||||
using Nop.Data.Mapping.Builders;
|
using Nop.Data.Mapping.Builders;
|
||||||
using Nop.Plugin.Misc.AIPlugin.Domains;
|
using Nop.Plugin.Misc.FruitBankPlugin.Domains;
|
||||||
|
|
||||||
namespace Nop.Plugin.Misc.AIPlugin.Mapping.Builders;
|
namespace Nop.Plugin.Misc.FruitBankPlugin.Mapping.Builders;
|
||||||
|
|
||||||
public class PluginBuilder : NopEntityBuilder<CustomTable>
|
public class PluginBuilder : NopEntityBuilder<CustomTable>
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
using Nop.Data.Mapping;
|
using Nop.Data.Mapping;
|
||||||
|
|
||||||
namespace Nop.Plugin.Misc.AIPlugin.Mapping;
|
namespace Nop.Plugin.Misc.FruitBankPlugin.Mapping;
|
||||||
|
|
||||||
public partial class NameCompatibility : INameCompatibility
|
public partial class NameCompatibility : INameCompatibility
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
using FluentMigrator;
|
using FluentMigrator;
|
||||||
using Nop.Data.Extensions;
|
using Nop.Data.Extensions;
|
||||||
using Nop.Data.Migrations;
|
using Nop.Data.Migrations;
|
||||||
using Nop.Plugin.Misc.AIPlugin.Domains;
|
using Nop.Plugin.Misc.FruitBankPlugin.Domains;
|
||||||
|
|
||||||
namespace Nop.Plugin.Misc.AIPlugin.Migrations;
|
namespace Nop.Plugin.Misc.FruitBankPlugin.Migrations;
|
||||||
|
|
||||||
//2024-10-31
|
//2024-10-31
|
||||||
[NopMigration("2025-08-29 12:07:22", "Nop.Plugin.Misc.AIPlugin schema", MigrationProcessType.Installation)]
|
[NopMigration("2025-08-29 12:07:22", "Nop.Plugin.Misc.FruitBankPlugin schema", MigrationProcessType.Installation)]
|
||||||
public class SchemaMigration : AutoReversingMigration
|
public class SchemaMigration : AutoReversingMigration
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<TargetFramework>net9.0</TargetFramework>
|
<TargetFramework>net9.0</TargetFramework>
|
||||||
<OutputPath>$(SolutionDir)\Presentation\Nop.Web\Plugins\Misc.AIPlugin</OutputPath>
|
<OutputPath>$(SolutionDir)\Presentation\Nop.Web\Plugins\Misc.FruitBankPlugin</OutputPath>
|
||||||
<OutDir>$(OutputPath)</OutDir>
|
<OutDir>$(OutputPath)</OutDir>
|
||||||
<!--Set this parameter to true to get the dlls copied from the NuGet cache to the output of your project.
|
<!--Set this parameter to true to get the dlls copied from the NuGet cache to the output of your project.
|
||||||
You need to set this parameter to true if your plugin has a nuget package
|
You need to set this parameter to true if your plugin has a nuget package
|
||||||
|
|
@ -49,7 +49,6 @@
|
||||||
<Folder Include="Areas\Admin\Extensions\" />
|
<Folder Include="Areas\Admin\Extensions\" />
|
||||||
<Folder Include="Areas\Admin\Factories\" />
|
<Folder Include="Areas\Admin\Factories\" />
|
||||||
<Folder Include="Areas\Admin\Validators\" />
|
<Folder Include="Areas\Admin\Validators\" />
|
||||||
<Folder Include="Controllers\" />
|
|
||||||
<Folder Include="Extensions\" />
|
<Folder Include="Extensions\" />
|
||||||
<Folder Include="Factories\" />
|
<Folder Include="Factories\" />
|
||||||
<Folder Include="Models\" />
|
<Folder Include="Models\" />
|
||||||
|
|
@ -57,6 +56,12 @@
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<None Update="Areas\Admin\Views\Configure\Configure.cshtml">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
|
<None Update="Views\Checkout\PendingMeasurementWarning.cshtml">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</None>
|
||||||
<None Update="Views\ProductAIListWidget.cshtml">
|
<None Update="Views\ProductAIListWidget.cshtml">
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
using global::Nop.Core.Configuration;
|
using global::Nop.Core.Configuration;
|
||||||
|
|
||||||
|
|
||||||
namespace Nop.Plugin.Misc.AIPlugin
|
namespace Nop.Plugin.Misc.FruitBankPlugin
|
||||||
{
|
{
|
||||||
public class OpenAiSettings : ISettings
|
public class OpenAiSettings : ISettings
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,84 @@
|
||||||
|
using Nop.Core.Caching;
|
||||||
|
using Nop.Core.Domain.Catalog;
|
||||||
|
using Nop.Core.Domain.Customers;
|
||||||
|
using Nop.Core;
|
||||||
|
using Nop.Data;
|
||||||
|
using Nop.Services.Catalog;
|
||||||
|
using Nop.Services.Customers;
|
||||||
|
using Nop.Services.Discounts;
|
||||||
|
using Nop.Services.Localization;
|
||||||
|
using Nop.Services.Logging;
|
||||||
|
using Nop.Core.Domain.Directory;
|
||||||
|
using Nop.Services.Directory;
|
||||||
|
using Nop.Core.Domain.Discounts;
|
||||||
|
using Nop.Core.Domain.Stores;
|
||||||
|
|
||||||
|
namespace Nop.Plugin.Misc.FruitBankPlugin.Services;
|
||||||
|
|
||||||
|
public class CustomPriceCalculationService : PriceCalculationService
|
||||||
|
{
|
||||||
|
private readonly IRepository<Product> _productRepository;
|
||||||
|
private readonly IProductAttributeService _productAttributeService;
|
||||||
|
private readonly ISpecificationAttributeService _specificationAttributeService;
|
||||||
|
private readonly ILocalizationService _localizationService;
|
||||||
|
private readonly IProductService _productService;
|
||||||
|
|
||||||
|
public CustomPriceCalculationService(
|
||||||
|
IRepository<Product> productRepository,
|
||||||
|
// inject all base deps
|
||||||
|
CatalogSettings catalogSettings,
|
||||||
|
CurrencySettings currencySettings,
|
||||||
|
ICategoryService categoryService,
|
||||||
|
ICurrencyService currencyService,
|
||||||
|
IManufacturerService manufacturerService,
|
||||||
|
IProductAttributeParser productAttributeParser,
|
||||||
|
IProductAttributeService productAttributeService,
|
||||||
|
ISpecificationAttributeService specificationAttributeService,
|
||||||
|
IProductService productService,
|
||||||
|
ICustomerService customerService,
|
||||||
|
IDiscountService discountService,
|
||||||
|
IDiscountPluginManager discountPluginManager,
|
||||||
|
ILocalizationService localizationService,
|
||||||
|
IStaticCacheManager cacheManager,
|
||||||
|
IWorkContext workContext,
|
||||||
|
ILogger logger)
|
||||||
|
: base(catalogSettings, currencySettings, categoryService, currencyService, customerService, discountService, manufacturerService,
|
||||||
|
productAttributeParser, productService,
|
||||||
|
cacheManager)
|
||||||
|
{
|
||||||
|
_productRepository = productRepository;
|
||||||
|
// assign all base deps to local private vars if needed
|
||||||
|
_productAttributeService = productAttributeService;
|
||||||
|
_specificationAttributeService = specificationAttributeService;
|
||||||
|
_localizationService = localizationService;
|
||||||
|
_productService = productService;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//decimal? overriddenProductPrice = null
|
||||||
|
|
||||||
|
public override async Task<(decimal priceWithoutDiscounts, decimal finalPrice, decimal appliedDiscountAmount, List<Discount> appliedDiscounts)> GetFinalPriceAsync(
|
||||||
|
Product product, Customer customer, Store store, decimal? overriddenProductPrice, decimal additionalCharge = 0, bool includeDiscounts = true,
|
||||||
|
int quantity = 1, DateTime? rentalStartDate = null, DateTime? rentalEndDate = null)
|
||||||
|
{
|
||||||
|
|
||||||
|
var productAttributeMappings = await _productAttributeService.GetAllProductAttributesAsync(product.Id);
|
||||||
|
//Product Attributes
|
||||||
|
foreach (var pam in productAttributeMappings)
|
||||||
|
{
|
||||||
|
var attributes = await _productAttributeService.GetProductAttributeValuesAsync(pam.Id);
|
||||||
|
foreach (var attr in attributes)
|
||||||
|
{
|
||||||
|
// you can check for specific attribute by its name or id
|
||||||
|
if (attr.Name == "NeedsToBeMeasured" && attr.IsPreSelected)
|
||||||
|
{
|
||||||
|
return (0m, 0m, 0m, new List<Discount>());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return await base.GetFinalPriceAsync(product, customer, store, overriddenProductPrice, additionalCharge, includeDiscounts, quantity, rentalStartDate, rentalEndDate);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,71 @@
|
||||||
|
using System.Linq;
|
||||||
|
using Nop.Core.Domain.Catalog;
|
||||||
|
using Nop.Core.Domain.Orders;
|
||||||
|
using Nop.Services.Catalog;
|
||||||
|
using Nop.Services.Common;
|
||||||
|
using Nop.Services.Events;
|
||||||
|
using Nop.Services.Orders;
|
||||||
|
|
||||||
|
namespace Nop.Plugin.YourCompany.Measurement.Services
|
||||||
|
{
|
||||||
|
public class OrderPlacedConsumer : IConsumer<OrderPlacedEvent>
|
||||||
|
{
|
||||||
|
private readonly IGenericAttributeService _genericAttributeService;
|
||||||
|
private readonly IProductService _productService;
|
||||||
|
private readonly IOrderService _orderService;
|
||||||
|
private readonly IProductAttributeService _productAttributeService;
|
||||||
|
|
||||||
|
public OrderPlacedConsumer(
|
||||||
|
IGenericAttributeService genericAttributeService,
|
||||||
|
IProductService productService,
|
||||||
|
IOrderService orderService,
|
||||||
|
IProductAttributeService productAttributeService)
|
||||||
|
{
|
||||||
|
_genericAttributeService = genericAttributeService;
|
||||||
|
_productService = productService;
|
||||||
|
_orderService = orderService;
|
||||||
|
_productAttributeService = productAttributeService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task HandleEventAsync(OrderPlacedEvent eventMessage)
|
||||||
|
{
|
||||||
|
var order = eventMessage.Order;
|
||||||
|
var orderItems = await _orderService.GetOrderItemsAsync(order.Id);
|
||||||
|
bool requiresMeasurement = false;
|
||||||
|
|
||||||
|
foreach (var item in orderItems)
|
||||||
|
{
|
||||||
|
var product = await _productService.GetProductByIdAsync(item.ProductId);
|
||||||
|
|
||||||
|
// itt pl. egy custom flag a producton, ami jelzi, hogy mérés kell hozzá
|
||||||
|
// akár egy product attribute is lehet, vagy egy saját extension metódus
|
||||||
|
if (product != null)
|
||||||
|
{
|
||||||
|
var productAttributeMappings = await _productAttributeService.GetProductAttributeMappingsByProductIdAsync(product.Id);
|
||||||
|
//Product Attributes
|
||||||
|
foreach (var pam in productAttributeMappings)
|
||||||
|
{
|
||||||
|
var attributes = await _productAttributeService.GetProductAttributeValuesAsync(pam.Id);
|
||||||
|
foreach (var attr in attributes)
|
||||||
|
{
|
||||||
|
// you can check for specific attribute by its name or id
|
||||||
|
if (attr.Name == "NeedsToBeMeasured" && attr.IsPreSelected)
|
||||||
|
{
|
||||||
|
requiresMeasurement = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (requiresMeasurement)
|
||||||
|
{
|
||||||
|
// itt adjuk hozzá a GenericAttribute flag-et az orderhez
|
||||||
|
await _genericAttributeService.SaveAttributeAsync(order,
|
||||||
|
"PendingMeasurement", true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
using Microsoft.AspNetCore.SignalR;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace Nop.Plugin.Misc.FruitBankPlugin.Services
|
||||||
|
{
|
||||||
|
class FruitBankHub : Hub
|
||||||
|
{
|
||||||
|
public async Task SendMessage(string user, string message)
|
||||||
|
{
|
||||||
|
await Clients.All.SendAsync("ReceiveMessage", user, message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
using Nop.Plugin.Misc.AIPlugin;
|
using Nop.Plugin.Misc.FruitBankPlugin;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Net.Http.Headers;
|
using System.Net.Http.Headers;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
@ -6,7 +6,7 @@ using System.Text.Json;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Nop.Services.Configuration;
|
using Nop.Services.Configuration;
|
||||||
|
|
||||||
namespace Nop.Plugin.Misc.AIPlugin.Services
|
namespace Nop.Plugin.Misc.FruitBankPlugin.Services
|
||||||
{
|
{
|
||||||
|
|
||||||
public class OpenAiService
|
public class OpenAiService
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
using Nop.Core.Domain.Orders;
|
||||||
|
using Nop.Services.Common;
|
||||||
|
|
||||||
|
namespace Nop.Plugin.Misc.FruitBankPlugin.Services
|
||||||
|
{
|
||||||
|
public interface IOrderMeasurementService
|
||||||
|
{
|
||||||
|
Task<bool> IsPendingMeasurementAsync(Order order);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class OrderMeasurementService : IOrderMeasurementService
|
||||||
|
{
|
||||||
|
private readonly IGenericAttributeService _genericAttributeService;
|
||||||
|
|
||||||
|
public OrderMeasurementService(IGenericAttributeService genericAttributeService)
|
||||||
|
{
|
||||||
|
_genericAttributeService = genericAttributeService;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task<bool> IsPendingMeasurementAsync(Order order)
|
||||||
|
{
|
||||||
|
if (order == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return await _genericAttributeService.GetAttributeAsync<bool>(
|
||||||
|
order, "PendingMeasurement", order.StoreId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,15 @@
|
||||||
|
@{
|
||||||
|
Layout = "_RootLayout"; // a front-endhez használt layout
|
||||||
|
}
|
||||||
|
|
||||||
|
<h3>Rendelés mérés alatt</h3>
|
||||||
|
<p>
|
||||||
|
Ez a rendelés még mérés alatt áll, az ár még nem végleges.
|
||||||
|
Értesítést fog kapni, amikor a fizetés lehetséges.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<a href="@Url.Action("Index", "ShoppingCart")" class="btn btn-secondary">
|
||||||
|
Vissza a kosárhoz
|
||||||
|
</a>
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -9,7 +9,7 @@
|
||||||
@using Nop.Services.Events
|
@using Nop.Services.Events
|
||||||
@using Nop.Web.Framework.Events
|
@using Nop.Web.Framework.Events
|
||||||
@using Nop.Web.Framework.Infrastructure
|
@using Nop.Web.Framework.Infrastructure
|
||||||
@using Nop.Plugin.Misc.AIPlugin
|
@using Nop.Plugin.Misc.FruitBankPlugin
|
||||||
@* @using Nop.Plugin.Misc.AIPlugin.Models *@
|
@* @using Nop.Plugin.Misc.FruitBankPlugin.Models *@
|
||||||
@using Nop.Plugin.Misc.AIPlugin.Services
|
@using Nop.Plugin.Misc.FruitBankPlugin.Services
|
||||||
@* @using Nop.Plugin.Misc.AIPlugin.Hubs *@
|
@* @using Nop.Plugin.Misc.FruitBankPlugin.Hubs *@
|
||||||
|
|
@ -1,13 +1,13 @@
|
||||||
{
|
{
|
||||||
"Group": "Misc",
|
"Group": "Misc",
|
||||||
"FriendlyName": "AIPlugin",
|
"FriendlyName": "FruitBankPlugin",
|
||||||
"SystemName": "Misc.AIPlugin",
|
"SystemName": "Misc.FruitBankPlugin",
|
||||||
"Version": "1.00",
|
"Version": "1.00",
|
||||||
"SupportedVersions": [
|
"SupportedVersions": [
|
||||||
"4.80"
|
"4.80"
|
||||||
],
|
],
|
||||||
"Author": "Adam Gelencser",
|
"Author": "Adam Gelencser",
|
||||||
"DisplayOrder": 1,
|
"DisplayOrder": 1,
|
||||||
"FileName": "Nop.Plugin.Misc.AIPlugin.dll",
|
"FileName": "Nop.Plugin.Misc.FruitBankPlugin.dll",
|
||||||
"Description": ""
|
"Description": ""
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue