Mango.Nop.Plugins/Nop.Plugin.Misc.AIPlugin/Components/CustomerCreditWidgetViewCom...

131 lines
5.3 KiB
C#

using System.Text.Json;
using Microsoft.AspNetCore.Mvc;
using Nop.Core.Domain.Common;
using Nop.Core.Domain.Customers;
using Nop.Plugin.Misc.FruitBankPlugin.Models;
using Nop.Plugin.Misc.FruitBankPlugin.Services;
using Nop.Services.Customers;
using Nop.Web.Areas.Admin.Models.Customers;
using Nop.Web.Framework.Components;
namespace Nop.Plugin.Misc.FruitBankPlugin.Components;
[ViewComponent(Name = "CustomerCreditWidget")]
public class CustomerCreditWidgetViewComponent : NopViewComponent
{
private readonly ICustomerCreditService _customerCreditService;
private readonly FruitBankAttributeService _attributeService;
private readonly ICustomerService _customerService;
public CustomerCreditWidgetViewComponent(
ICustomerCreditService customerCreditService,
FruitBankAttributeService attributeService,
ICustomerService customerService)
{
_customerCreditService = customerCreditService;
_attributeService = attributeService;
_customerService = customerService;
}
public async Task<IViewComponentResult> InvokeAsync(string widgetZone, object additionalData)
{
if (additionalData is not CustomerModel customerModel) return Content("");
var customerId = customerModel.Id;
var credit = await _customerCreditService.GetByCustomerIdAsync(customerId);
var outstanding = await _customerCreditService.GetOutstandingBalanceAsync(customerId);
// Hiányzó attribútum (null) = köteles — a kapu is így dönt (CreateMissingEkaerHistories: csak az explicit
// false mentesít); a checkbox pipáltat mutat, amíg explicit ki nem veszik.
var isEkaer = await _attributeService
.GetGenericAttributeValueAsync<Customer, bool?>(customerId, FruitBankPluginConst.IsEkaerAttribute, storeId: 0) ?? true;
var model = new CustomerCreditWidgetModel
{
CustomerId = customerId,
HasCreditLimit = credit != null,
CreditLimit = credit?.CreditLimit ?? 0m,
OutstandingBalance = outstanding,
RemainingCredit = credit != null ? credit.CreditLimit - outstanding : (decimal?)null,
Comment = credit?.Comment,
IsEkaer = isEkaer
};
await PopulateSitesAsync(model, customerId);
await PopulatePlatesAsync(model, customerId);
return View("~/Plugins/Misc.FruitBankPlugin/Views/CustomerCreditWidget.cshtml", model);
}
private async Task PopulatePlatesAsync(CustomerCreditWidgetModel model, int customerId)
{
var json = await _attributeService
.GetGenericAttributeValueAsync<Customer, string>(customerId, FruitBankPluginConst.CustomerLicensePlatesAttribute, storeId: 0);
var entries = ParsePlates(json);
model.LicensePlates = entries
.Select(e => new CustomerLicensePlateRow { Plate = e.Plate, IsDefault = e.IsDefault })
.ToList();
model.PlateCount = model.LicensePlates.Count;
model.DefaultPlate = model.LicensePlates.FirstOrDefault(p => p.IsDefault)?.Plate;
}
private static List<CustomerLicensePlateEntry> ParsePlates(string? json)
{
if (string.IsNullOrWhiteSpace(json)) return new();
try { return JsonSerializer.Deserialize<List<CustomerLicensePlateEntry>>(json) ?? new(); }
catch { return new(); }
}
// Merge the customer's current addresses with the saved site list (orphaned
// address ids — deleted addresses — are dropped because we iterate addresses).
private async Task PopulateSitesAsync(CustomerCreditWidgetModel model, int customerId)
{
var addresses = await _customerService.GetAddressesByCustomerIdAsync(customerId);
var savedJson = await _attributeService
.GetGenericAttributeValueAsync<Customer, string>(customerId, FruitBankPluginConst.CustomerSitesAttribute, storeId: 0);
var saved = ParseSites(savedJson);
var savedById = saved.ToDictionary(s => s.AddressId);
foreach (var addr in addresses)
{
savedById.TryGetValue(addr.Id, out var entry);
model.SiteAddresses.Add(new CustomerSiteAddressRow
{
AddressId = addr.Id,
Display = FormatAddress(addr),
IsSite = entry != null,
IsDefault = entry?.IsDefault ?? false
});
}
var sites = model.SiteAddresses.Where(a => a.IsSite).ToList();
model.SiteCount = sites.Count;
model.DefaultSiteDisplay = sites.FirstOrDefault(a => a.IsDefault)?.Display;
}
private static List<CustomerSiteEntry> ParseSites(string? json)
{
if (string.IsNullOrWhiteSpace(json)) return new();
try { return JsonSerializer.Deserialize<List<CustomerSiteEntry>>(json) ?? new(); }
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 parts = new[] { name, a.Address1, locality }
.Where(p => !string.IsNullOrWhiteSpace(p));
var display = string.Join(", ", parts);
return string.IsNullOrWhiteSpace(display) ? $"#{a.Id}" : display;
}
}