using System.Text.Json; using FruitBank.Common.Interfaces; using Microsoft.AspNetCore.Mvc; 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.Plugin.Misc.FruitBankPlugin.Domains.DataLayer; using Nop.Plugin.Misc.FruitBankPlugin.Models; using Nop.Plugin.Misc.FruitBankPlugin.Models.Orders; using Nop.Plugin.Misc.FruitBankPlugin.Services; using Nop.Services.Common; using Nop.Services.Customers; using Nop.Web.Areas.Admin.Models.Catalog; using Nop.Web.Areas.Admin.Models.Orders; using Nop.Web.Framework.Components; namespace Nop.Plugin.Misc.FruitBankPlugin.Components { [ViewComponent(Name = "OrderAttributes")] public class OrderAttributesViewComponent : NopViewComponent { private readonly FruitBankAttributeService _fruitBankAttributeService; private readonly IWorkContext _workContext; private readonly IStoreContext _storeContext; private readonly ICustomerService _customerService; private FruitBankDbContext _dbContext; public OrderAttributesViewComponent(FruitBankDbContext dbContext, FruitBankAttributeService fruitBankAttributeService, IWorkContext workContext, IStoreContext storeContext, ICustomerService customerService) { _workContext = workContext; _storeContext = storeContext; _fruitBankAttributeService = fruitBankAttributeService; _customerService = customerService; _dbContext = dbContext; } public async Task InvokeAsync(string widgetZone, object additionalData) { if (additionalData is not OrderModel orderModel) return Content(""); var model = new OrderAttributesModel { OrderId = orderModel.Id }; if (model.OrderId > 0) { var orderDto = await _dbContext.OrderDtos.GetByIdAsync(model.OrderId, true); model.IsMeasurable = orderDto.IsMeasurable; model.DateOfReceipt = orderDto.DateOfReceipt; model.OrderDto = orderDto; // Site (telephely) + license plate (rendszám) model.CustomerId = orderDto.CustomerId; model.Site = orderDto.Site; model.LicensePlate = orderDto.LicensePlate; model.CustomerSites = await BuildCustomerSiteOptionsAsync(orderDto.CustomerId); model.CustomerLicensePlateOptions = await BuildCustomerPlateOptionsAsync(orderDto.CustomerId); } return View("~/Plugins/Misc.FruitBankPlugin/Views/OrderAttributes.cshtml", model); } // The customer's current sites (telephely) → selector options. Orphaned site // ids (deleted addresses) drop out because we iterate the live addresses. private async Task> BuildCustomerSiteOptionsAsync(int customerId) { if (customerId <= 0) return new(); var json = await _fruitBankAttributeService .GetGenericAttributeValueAsync(customerId, FruitBankPluginConst.CustomerSitesAttribute, 0); if (string.IsNullOrWhiteSpace(json)) return new(); List entries; try { entries = JsonSerializer.Deserialize>(json) ?? new(); } catch { return new(); } if (entries.Count == 0) return new(); var byId = entries.GroupBy(e => e.AddressId).ToDictionary(g => g.Key, g => g.First()); var addresses = await _customerService.GetAddressesByCustomerIdAsync(customerId); return addresses .Where(a => byId.ContainsKey(a.Id)) .Select(a => new OrderSiteOption { AddressId = a.Id, Display = FormatAddress(a), IsDefault = byId[a.Id].IsDefault }) .ToList(); } private async Task> BuildCustomerPlateOptionsAsync(int customerId) { if (customerId <= 0) return new(); var json = await _fruitBankAttributeService .GetGenericAttributeValueAsync(customerId, FruitBankPluginConst.CustomerLicensePlatesAttribute, 0); if (string.IsNullOrWhiteSpace(json)) return new(); try { var entries = JsonSerializer.Deserialize>(json) ?? new(); return entries.Select(e => e.Plate).Where(p => !string.IsNullOrWhiteSpace(p)).Distinct().ToList(); } catch { return new(); } } private static string FormatAddress(Address a) { var name = !string.IsNullOrWhiteSpace(a.Company) ? a.Company : $"{a.FirstName} {a.LastName}".Trim(); var locality = $"{a.ZipPostalCode} {a.City}".Trim(); var display = string.Join(", ", new[] { name, a.Address1, locality }.Where(p => !string.IsNullOrWhiteSpace(p))); return string.IsNullOrWhiteSpace(display) ? $"#{a.Id}" : display; } } }