using FruitBank.Common.Interfaces; using FruitBank.Common.Server; using Mango.Nop.Core.Dtos; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Logging; using Microsoft.IdentityModel.Tokens; using Nop.Core; using Nop.Core.Domain.Catalog; using Nop.Core.Domain.Common; using Nop.Core.Domain.Customers; using Nop.Core.Domain.Orders; using Nop.Core.Domain.Tax; using Nop.Core.Events; using Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer; using Nop.Plugin.Misc.FruitBankPlugin.Models; using Nop.Plugin.Misc.FruitBankPlugin.Models.Orders; using Nop.Services.Catalog; using Nop.Services.Common; using Nop.Services.Events; using Nop.Services.Localization; using Nop.Services.Orders; using Nop.Services.Plugins; using Nop.Web.Framework.Events; using Nop.Web.Framework.Menu; using Nop.Web.Models.Sitemap; using System.Linq; namespace Nop.Plugin.Misc.FruitBankPlugin.Services { public class EventConsumer : BaseAdminMenuCreatedEventConsumer, IConsumer>, IConsumer>, IConsumer, IConsumer>, IConsumer { private readonly IGenericAttributeService _genericAttributeService; private readonly IProductService _productService; private readonly ISpecificationAttributeService _specificationAttributeService; private readonly IOrderService _orderService; private readonly IProductAttributeService _productAttributeService; private readonly IWorkContext _workContext; private readonly IStoreContext _storeContext; private readonly IAdminMenu _adminMenu; private readonly ILocalizationService _localizationService; private readonly IHttpContextAccessor _httpContextAccessor; private readonly IAddressService _addressService; private readonly FruitBankAttributeService _fruitBankAttributeService; private readonly FruitBankDbContext _dbContext; public EventConsumer( IGenericAttributeService genericAttributeService, IProductService productService, ISpecificationAttributeService specificationAttributeService, IOrderService orderService, IProductAttributeService productAttributeService, IPluginManager pluginManager, IWorkContext workContext, IStoreContext storeContext, IAdminMenu adminMenu, ILocalizationService localizationService, IHttpContextAccessor httpContextAccessor, IAddressService addressService, FruitBankAttributeService fruitBankAttributeService, FruitBankDbContext dbContext) : base(pluginManager) { _genericAttributeService = genericAttributeService; _productService = productService; _specificationAttributeService = specificationAttributeService; _orderService = orderService; _productAttributeService = productAttributeService; _workContext = workContext; _storeContext = storeContext; _adminMenu = adminMenu; _localizationService = localizationService; _httpContextAccessor = httpContextAccessor; _addressService = addressService; _fruitBankAttributeService = fruitBankAttributeService; _dbContext = dbContext; } protected override string PluginSystemName => "Misc.FruitBankPlugin"; public async Task HandleEventAsync(OrderPlacedEvent eventMessage) { } public async Task HandleEventAsync(EntityUpdatedEvent eventMessage) { await SaveOrderCustomAttributesAsync(eventMessage.Entity); } private async Task SaveOrderCustomAttributesAsync(Order order) { if (order == null) return; var hasForm = _httpContextAccessor.HttpContext?.Request?.HasFormContentType ?? false; var form = hasForm ? _httpContextAccessor.HttpContext.Request.Form : null; if (form == null || form.Count == 0) return; //if (form.ContainsKey(nameof(IMeasurable.IsMeasurable))) //{ // var isMeasurable = form[nameof(IMeasurable.IsMeasurable)].ToString().Contains("true"); // //var isMeasurable = CommonHelper.To(form[nameof(IMeasurable.IsMeasurable)].ToString()); // await _fruitBankAttributeService.InsertOrUpdateGenericAttributeAsync(order.Id, nameof(IMeasurable.IsMeasurable), isMeasurable); //} if (form.ContainsKey(nameof(IOrderDto.DateOfReceipt))) { var dateOfReceiptString = form[nameof(IOrderDto.DateOfReceipt)]; if (string.IsNullOrWhiteSpace(dateOfReceiptString)) return; if (DateTime.TryParse(dateOfReceiptString, out var dateOfReceipt)) await _fruitBankAttributeService.InsertOrUpdateGenericAttributeAsync(order.Id, nameof(IOrderDto.DateOfReceipt), dateOfReceipt); } } public override async Task HandleEventAsync(AdminMenuCreatedEvent eventMessage) { var rootNode = eventMessage.RootMenuItem; var shippingsListMenuItem = new AdminMenuItem { Visible = true, SystemName = "FruitBank", Title = await _localizationService.GetResourceAsync("Plugins.Misc.FruitBankPlugin.Menu.ShippingsList"), // You can localize this with await _localizationService.GetResourceAsync("...") IconClass = "fas fa-shipping-fast", Url = _adminMenu.GetMenuItemUrl("Shipping", "List") }; var createShippingMenuItem = new AdminMenuItem { Visible = true, SystemName = "Shippings.Create", Title = "Create Shipping", IconClass = "far fa-circle", Url = _adminMenu.GetMenuItemUrl("Shipping", "Create") }; var editShippingMenuItem = new AdminMenuItem { Visible = true, SystemName = "Shippings.Edit", Title = "Edit Shipping", IconClass = "far fa-circle", Url = _adminMenu.GetMenuItemUrl("Shipping", "Edit") }; // Create a new top-level menu item var shippingsMenuItem = new AdminMenuItem { Visible = true, SystemName = "FruitBank", Title = await _localizationService.GetResourceAsync("Plugins.Misc.FruitBankPlugin.Menu.Shippings"), // You can localize this with await _localizationService.GetResourceAsync("...") IconClass = "fas fa-shipping-fast", //Url = _adminMenu.GetMenuItemUrl("Shipping", "List") ChildNodes = [shippingsListMenuItem, createShippingMenuItem, editShippingMenuItem] }; var shippingConfigurationItem = rootNode; shippingConfigurationItem.ChildNodes.Insert(2, shippingsMenuItem); var invoiceListMenuItem = new AdminMenuItem { Visible = true, SystemName = "FruitBank", Title = await _localizationService.GetResourceAsync("Plugins.Misc.FruitBankPlugin.Menu.InvoicesList"), // You can localize this with await _localizationService.GetResourceAsync("...") IconClass = "fas fa-file-invoice", Url = _adminMenu.GetMenuItemUrl("Invoices", "List") }; // Create a new top-level menu item var invoicesMenuItem = new AdminMenuItem { Visible = true, SystemName = "FruitBank", Title = await _localizationService.GetResourceAsync("Plugins.Misc.FruitBankPlugin.Menu.Invoices"), // You can localize this with await _localizationService.GetResourceAsync("...") IconClass = "fas fa-file-invoice", //Url = _adminMenu.GetMenuItemUrl("Shipping", "List") ChildNodes = [invoiceListMenuItem] }; var invoiceConfigurationItem = rootNode; invoiceConfigurationItem.ChildNodes.Insert(2, invoicesMenuItem); var configurationItem = rootNode.ChildNodes.FirstOrDefault(node => node.SystemName.Equals("Configuration")); if (configurationItem is null) return; var shippingItem = configurationItem.ChildNodes.FirstOrDefault(node => node.SystemName.Equals("Shipping")); var widgetsItem = configurationItem.ChildNodes.FirstOrDefault(node => node.SystemName.Equals("Widgets")); if (shippingItem is null && widgetsItem is null) return; var index = shippingItem is not null ? configurationItem.ChildNodes.IndexOf(shippingItem) : -1; if (index < 0) index = widgetsItem is not null ? configurationItem.ChildNodes.IndexOf(widgetsItem) : -1; if (index < 0) return; configurationItem.ChildNodes.Insert(index + 1, new AdminMenuItem { Visible = true, SystemName = "FruitBank", Title = await _localizationService.GetResourceAsync("Plugins.Misc.FruitBankPlugin.Menu.AI"), IconClass = "far fa-dot-circle", ChildNodes = new List { new() { Visible = true, SystemName = "FruitBank", Title = await _localizationService.GetResourceAsync("Plugins.Misc.FruitBankPlugin.Menu.Configure"), IconClass = "far fa-circle", Url = _adminMenu.GetMenuItemUrl("FruitBankPlugin", "Configure"), } } }); } public async Task HandleEventAsync(EntityInsertedEvent eventMessage) { await ProcessCustomerEventAsync(eventMessage?.Entity); } public async Task HandleEventAsync(EntityUpdatedEvent eventMessage) { await ProcessCustomerEventAsync(eventMessage?.Entity); } private async Task ProcessCustomerEventAsync(Customer customer) { if (customer == null) { return; } if (!IsRegisteredCustomer(customer)) { return; } await EnsureBillingAddressAsync(customer); await SynchronizeTaxInformationAsync(customer); } private bool IsRegisteredCustomer(Customer customer) { var customerRoles = _dbContext.GetCustomerRolesByCustomerId(customer.Id); return customerRoles?.Any(role => role.SystemName == "Registered") ?? false; } private async Task EnsureBillingAddressAsync(Customer customer) { if (customer.BillingAddressId != null) { return; } var address = new Address { ZipPostalCode = customer.ZipPostalCode, City = customer.City, Address1 = customer.StreetAddress, Address2 = customer.StreetAddress2, CountryId = customer.CountryId > 0 ? customer.CountryId : null, StateProvinceId = customer.StateProvinceId > 0 ? customer.StateProvinceId : null, PhoneNumber = customer.Phone, Company = customer.Company, FirstName = customer.FirstName, LastName = customer.LastName, Email = customer.Email, County = customer.County }; await _addressService.InsertAddressAsync(address); await _dbContext.AddCustomerAddressMappingAsync(customer.Id, address.Id); customer.BillingAddressId = address.Id; } private async Task SynchronizeTaxInformationAsync(Customer customer) { var taxId = await _fruitBankAttributeService.GetGenericAttributeValueAsync(customer.Id, "TaxId"); if (!string.IsNullOrWhiteSpace(taxId) && string.IsNullOrWhiteSpace(customer.VatNumber)) { customer.VatNumber = taxId; } else if (string.IsNullOrWhiteSpace(taxId) && !string.IsNullOrWhiteSpace(customer.VatNumber)) { await _fruitBankAttributeService.InsertOrUpdateGenericAttributeAsync( customer.Id, "TaxId", customer.VatNumber); } } } }