using System.Text.Json; using Microsoft.AspNetCore.Mvc; using Nop.Core.Domain.Customers; using Nop.Core.Domain.Orders; using Nop.Plugin.Misc.FruitBankPlugin.Models; using Nop.Plugin.Misc.FruitBankPlugin.Services; using Nop.Services.Customers; using Nop.Services.Orders; using Nop.Services.Security; using Nop.Web.Framework; using Nop.Web.Framework.Controllers; using Nop.Web.Framework.Mvc.Filters; namespace Nop.Plugin.Misc.FruitBankPlugin.Areas.Admin.Controllers; /// /// Inline-save endpoints for the FruitBank order attributes (site / license plate) /// on the admin order page (rendered by OrderAttributesViewComponent). Stored as /// store-agnostic (StoreId 0) order generic attributes via , /// using the same keys the OrderDto exposes. /// [AuthorizeAdmin] [Area(AreaNames.ADMIN)] public class OrderAttributesController : BasePluginController { private readonly FruitBankAttributeService _attributeService; private readonly ICustomerService _customerService; private readonly IOrderService _orderService; private readonly IPermissionService _permissionService; public OrderAttributesController( FruitBankAttributeService attributeService, ICustomerService customerService, IOrderService orderService, IPermissionService permissionService) { _attributeService = attributeService; _customerService = customerService; _orderService = orderService; _permissionService = permissionService; } [HttpPost] [Route("Admin/OrderAttributes/SaveSite")] public async Task SaveSite(int orderId, int addressId) { if (!await _permissionService.AuthorizeAsync(StandardPermission.Security.ACCESS_ADMIN_PANEL)) return Json(new { success = false, error = "Access denied" }); var order = await _orderService.GetOrderByIdAsync(orderId); if (order == null) return Json(new { success = false, error = "Rendelés nem található" }); // Clear if (addressId <= 0) { await _attributeService.DeleteGenericAttributeAsync(orderId, FruitBankPluginConst.OrderSiteAttribute, 0); return Json(new { success = true, cleared = true }); } // The chosen address MUST be one of the customer's sites (telephely) — not a // shipping/billing address. var sitesJson = await _attributeService .GetGenericAttributeValueAsync(order.CustomerId, FruitBankPluginConst.CustomerSitesAttribute, 0); if (!ParseSiteAddressIds(sitesJson).Contains(addressId)) return Json(new { success = false, error = "A cím nem a vevő telephelye." }); var address = (await _customerService.GetAddressesByCustomerIdAsync(order.CustomerId)) .FirstOrDefault(a => a.Id == addressId); if (address == null) return Json(new { success = false, error = "Cím nem található" }); var customer = await _customerService.GetCustomerByIdAsync(order.CustomerId); var snapshot = OrderSiteSnapshotBuilder.FromAddress(address, customer?.VatNumber); var json = Newtonsoft.Json.JsonConvert.SerializeObject(snapshot); await _attributeService.InsertOrUpdateGenericAttributeAsync( orderId, FruitBankPluginConst.OrderSiteAttribute, json, 0); return Json(new { success = true, display = snapshot.Display }); } [HttpPost] [Route("Admin/OrderAttributes/SaveLicensePlate")] public async Task SaveLicensePlate(int orderId, string? licensePlate) { if (!await _permissionService.AuthorizeAsync(StandardPermission.Security.ACCESS_ADMIN_PANEL)) return Json(new { success = false, error = "Access denied" }); var order = await _orderService.GetOrderByIdAsync(orderId); if (order == null) return Json(new { success = false, error = "Rendelés nem található" }); var plate = licensePlate?.Trim().ToUpperInvariant(); if (string.IsNullOrWhiteSpace(plate)) { await _attributeService.DeleteGenericAttributeAsync(orderId, FruitBankPluginConst.OrderLicensePlateAttribute, 0); return Json(new { success = true, cleared = true }); } await _attributeService.InsertOrUpdateGenericAttributeAsync( orderId, FruitBankPluginConst.OrderLicensePlateAttribute, plate, 0); return Json(new { success = true, licensePlate = plate }); } private static HashSet ParseSiteAddressIds(string? json) { if (string.IsNullOrWhiteSpace(json)) return new(); try { var entries = JsonSerializer.Deserialize>(json) ?? new(); return entries.Select(e => e.AddressId).ToHashSet(); } catch { return new(); } } }