Compare commits

..

No commits in common. "7d82c8626164391a2fd6d22705d4135fdfa08c5f" and "e03a9cf6db32bb55de5cb231ac5904e87fd22da0" have entirely different histories.

27 changed files with 51 additions and 408 deletions

View File

@ -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.FruitBankPlugin.Components; using Nop.Plugin.Misc.AIPlugin.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.FruitBankPlugin namespace Nop.Plugin.Misc.AIPlugin
{ {
/// <summary> /// <summary>
/// Main plugin class /// Main plugin class
/// </summary> /// </summary>
public class FruitBankPlugin : BasePlugin, IWidgetPlugin public class AIPlugin : 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.FruitBankPlugin
//handle AdminMenuCreatedEvent //handle AdminMenuCreatedEvent
public FruitBankPlugin(IActionContextAccessor actionContextAccessor, public AIPlugin(IActionContextAccessor actionContextAccessor,
ISettingService settingService, ISettingService settingService,
//IWebHelper webHelper, //IWebHelper webHelper,
ILocalizationService localizationService, ILocalizationService localizationService,
@ -50,9 +50,6 @@ namespace Nop.Plugin.Misc.FruitBankPlugin
// --- 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
{ {
@ -91,9 +88,9 @@ namespace Nop.Plugin.Misc.FruitBankPlugin
// var pluginNode = new AdminMenuItem // var pluginNode = new AdminMenuItem
// { // {
// SystemName = "FruitBankPlugin.Configure", // SystemName = "AIPlugin.Configure",
// Title = "AI Assistant", // Title = "AI Assistant",
// Url = $"{_webHelper.GetStoreLocation()}Admin/FruitBankPluginAdmin/Configure", // Url = $"{_webHelper.GetStoreLocation()}Admin/AIPluginAdmin/Configure",
// Visible = true // Visible = true
// }; // };
// rootNode.ChildNodes.Add(pluginNode); // rootNode.ChildNodes.Add(pluginNode);
@ -131,15 +128,15 @@ namespace Nop.Plugin.Misc.FruitBankPlugin
{ {
new() new()
{ {
// SystemName = "FruitBankPlugin.Configure", // SystemName = "AIPlugin.Configure",
// Title = "AI Assistant", // Title = "AI Assistant",
// Url = $"{_webHelper.GetStoreLocation()}Admin/FruitBankPluginAdmin/Configure", // Url = $"{_webHelper.GetStoreLocation()}Admin/AIPluginAdmin/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("FruitBankPlugin", "Configure"), Url = _adminMenu.GetMenuItemUrl("AIPlugin", "Configure"),
//Url = "Admin/SignalRApi/Configure", //Url = "Admin/SignalRApi/Configure",
//ControllerName = "SignalRApi", //ControllerName = "SignalRApi",
//ActionName = "Configure", //ActionName = "Configure",
@ -151,7 +148,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin
public override string GetConfigurationPageUrl() public override string GetConfigurationPageUrl()
{ {
return _urlHelperFactory.GetUrlHelper(_actionContextAccessor.ActionContext).RouteUrl("Plugin.Misc.FruitBankPlugin.Configure"); return _urlHelperFactory.GetUrlHelper(_actionContextAccessor.ActionContext).RouteUrl("Plugin.Misc.AIPlugin.Configure");
} }
public Type GetWidgetViewComponent(string widgetZone) public Type GetWidgetViewComponent(string widgetZone)

View File

@ -1,21 +1,21 @@
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Models; using Nop.Plugin.Misc.AIPlugin.Areas.Admin.Models;
using Nop.Plugin.Misc.FruitBankPlugin; using Nop.Plugin.Misc.AIPlugin;
//using Nop.Plugin.Misc.FruitBankPlugin; //using Nop.Plugin.Misc.AIPlugin;
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.FruitBankPlugin.Controllers namespace Nop.Plugin.Misc.AIPlugin.Controllers
{ {
[Area("Admin")] [Area("Admin")]
public class FruitBankPluginAdminController : BasePluginController public class AIPluginAdminController : 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 FruitBankPluginAdminController(INotificationService notificationService, ISettingService settingService, OpenAiSettings settings) public AIPluginAdminController(INotificationService notificationService, ISettingService settingService, OpenAiSettings settings)
{ {
_notificationService = notificationService; _notificationService = notificationService;
_settingService = settingService; _settingService = settingService;
@ -29,7 +29,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.Controllers
{ {
ApiKey = _settings.ApiKey ApiKey = _settings.ApiKey
}; };
return View("~/Plugins/Misc.FruitBankPlugin/Areas/Admin/Views/Configure/Configure.cshtml", model); return View("~/Plugins/Misc.AIPlugin/Views/Configure/Configure.cshtml", model);
} }
[HttpPost] [HttpPost]

View File

@ -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.FruitBankPlugin.Areas.Admin.Models namespace Nop.Plugin.Misc.AIPlugin.Areas.Admin.Models
{ {
public record ConfigureModel public record ConfigureModel
{ {
[NopResourceDisplayName("Plugins.FruitBankPlugin.Fields.ApiKey")] [NopResourceDisplayName("Plugins.AIPlugin.Fields.ApiKey")]
public string ApiKey { get; set; } public string ApiKey { get; set; }
} }
} }

View File

@ -1,8 +1,8 @@
@model Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Models.ConfigureModel @model Nop.Plugin.Misc.AIPlugin.Models.ConfigureModel
@{ @{
Layout = "_AdminLayout"; Layout = "_AdminLayout";
NopHtml.SetActiveMenuItemSystemName("AiAssistant.Configure"); Html.SetActiveMenuItemSystemName("AiAssistant.Configure");
} }
<div class="card"> <div class="card">

View File

@ -2,8 +2,6 @@
@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

View File

@ -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.FruitBankPlugin.Components; namespace Nop.Plugin.Misc.AIPlugin.Components;
[ViewComponent(Name = "Custom")] [ViewComponent(Name = "Custom")]
public class CustomViewComponent : NopViewComponent public class CustomViewComponent : NopViewComponent

View File

@ -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.FruitBankPlugin.Components namespace Nop.Plugin.Misc.AIPlugin.Components
{ {
[ViewComponent(Name = "ProductAIWidget")] [ViewComponent(Name = "ProductAIWidget")]
@ -20,7 +20,7 @@ namespace Nop.Plugin.Misc.FruitBankPlugin.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.FruitBankPlugin/Views/ProductAIListWidget.cshtml", product); return View("~/Plugins/Misc.AIPlugin/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.FruitBankPlugin.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.FruitBankPlugin/Views/ProductAIWidget.cshtml", product); return View("~/Plugins/Misc.AIPlugin/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

View File

@ -1,16 +0,0 @@
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");
}
}
}

View File

@ -1,6 +1,6 @@
using Nop.Core; using Nop.Core;
namespace Nop.Plugin.Misc.FruitBankPlugin.Domains; namespace Nop.Plugin.Misc.AIPlugin.Domains;
public partial class CustomTable : BaseEntity public partial class CustomTable : BaseEntity
{ {

View File

@ -1,55 +0,0 @@
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
}
}
}

View File

@ -1,14 +0,0 @@
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";
}
}

View File

@ -1,14 +1,10 @@
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.FruitBankPlugin.Infrastructure; namespace Nop.Plugin.Misc.AIPlugin.Infrastructure;
public class PluginNopStartup : INopStartup public class PluginNopStartup : INopStartup
{ {
@ -24,28 +20,8 @@ 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>
@ -54,24 +30,10 @@ 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 => 4000; public int Order => 3000;
} }

View File

@ -1,10 +1,7 @@
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Routing;
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.FruitBankPlugin.Infrastructure; namespace Nop.Plugin.Misc.AIPlugin.Infrastructure;
/// <summary> /// <summary>
/// Represents plugin route provider /// Represents plugin route provider
@ -17,11 +14,7 @@ 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>

View File

@ -1,6 +1,6 @@
using Microsoft.AspNetCore.Mvc.Razor; using Microsoft.AspNetCore.Mvc.Razor;
namespace Nop.Plugin.Misc.FruitBankPlugin.Infrastructure; namespace Nop.Plugin.Misc.AIPlugin.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.FruitBankPlugin/Areas/Admin/Views/{context.ControllerName}/{context.ViewName}.cshtml" }.Concat(viewLocations); viewLocations = new[] { $"/Plugins/Nop.Plugin.Misc.AIPlugin/Areas/Admin/Views/{context.ControllerName}/{context.ViewName}.cshtml" }.Concat(viewLocations);
} }
else else
{ {
viewLocations = new[] { $"/Plugins/Nop.Plugin.Misc.FruitBankPlugin/Views/{context.ControllerName}/{context.ViewName}.cshtml" }.Concat(viewLocations); viewLocations = new[] { $"/Plugins/Nop.Plugin.Misc.AIPlugin/Views/{context.ControllerName}/{context.ViewName}.cshtml" }.Concat(viewLocations);
} }
return viewLocations; return viewLocations;

View File

@ -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.FruitBankPlugin.Domains; using Nop.Plugin.Misc.AIPlugin.Domains;
namespace Nop.Plugin.Misc.FruitBankPlugin.Mapping.Builders; namespace Nop.Plugin.Misc.AIPlugin.Mapping.Builders;
public class PluginBuilder : NopEntityBuilder<CustomTable> public class PluginBuilder : NopEntityBuilder<CustomTable>
{ {

View File

@ -1,6 +1,6 @@
using Nop.Data.Mapping; using Nop.Data.Mapping;
namespace Nop.Plugin.Misc.FruitBankPlugin.Mapping; namespace Nop.Plugin.Misc.AIPlugin.Mapping;
public partial class NameCompatibility : INameCompatibility public partial class NameCompatibility : INameCompatibility
{ {

View File

@ -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.FruitBankPlugin.Domains; using Nop.Plugin.Misc.AIPlugin.Domains;
namespace Nop.Plugin.Misc.FruitBankPlugin.Migrations; namespace Nop.Plugin.Misc.AIPlugin.Migrations;
//2024-10-31 //2024-10-31
[NopMigration("2025-08-29 12:07:22", "Nop.Plugin.Misc.FruitBankPlugin schema", MigrationProcessType.Installation)] [NopMigration("2025-08-29 12:07:22", "Nop.Plugin.Misc.AIPlugin schema", MigrationProcessType.Installation)]
public class SchemaMigration : AutoReversingMigration public class SchemaMigration : AutoReversingMigration
{ {
/// <summary> /// <summary>

View File

@ -2,7 +2,7 @@
<PropertyGroup> <PropertyGroup>
<TargetFramework>net9.0</TargetFramework> <TargetFramework>net9.0</TargetFramework>
<OutputPath>$(SolutionDir)\Presentation\Nop.Web\Plugins\Misc.FruitBankPlugin</OutputPath> <OutputPath>$(SolutionDir)\Presentation\Nop.Web\Plugins\Misc.AIPlugin</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,6 +49,7 @@
<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\" />
@ -56,12 +57,6 @@
</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>

View File

@ -1,7 +1,7 @@
using global::Nop.Core.Configuration; using global::Nop.Core.Configuration;
namespace Nop.Plugin.Misc.FruitBankPlugin namespace Nop.Plugin.Misc.AIPlugin
{ {
public class OpenAiSettings : ISettings public class OpenAiSettings : ISettings
{ {

View File

@ -1,84 +0,0 @@
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);
}
}

View File

@ -1,71 +0,0 @@
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);
}
}
}
}

View File

@ -1,18 +0,0 @@
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);
}
}
}

View File

@ -1,4 +1,4 @@
using Nop.Plugin.Misc.FruitBankPlugin; using Nop.Plugin.Misc.AIPlugin;
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.FruitBankPlugin.Services namespace Nop.Plugin.Misc.AIPlugin.Services
{ {
public class OpenAiService public class OpenAiService

View File

@ -1,29 +0,0 @@
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);
}
}
}

View File

@ -1,15 +0,0 @@
@{
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>

View File

@ -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.FruitBankPlugin @using Nop.Plugin.Misc.AIPlugin
@* @using Nop.Plugin.Misc.FruitBankPlugin.Models *@ @* @using Nop.Plugin.Misc.AIPlugin.Models *@
@using Nop.Plugin.Misc.FruitBankPlugin.Services @using Nop.Plugin.Misc.AIPlugin.Services
@* @using Nop.Plugin.Misc.FruitBankPlugin.Hubs *@ @* @using Nop.Plugin.Misc.AIPlugin.Hubs *@

View File

@ -1,13 +1,13 @@
{ {
"Group": "Misc", "Group": "Misc",
"FriendlyName": "FruitBankPlugin", "FriendlyName": "AIPlugin",
"SystemName": "Misc.FruitBankPlugin", "SystemName": "Misc.AIPlugin",
"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.FruitBankPlugin.dll", "FileName": "Nop.Plugin.Misc.AIPlugin.dll",
"Description": "" "Description": ""
} }