using FruitBank.Common.Entities; using Nop.Core.Domain.Orders; using Nop.Core.Domain.Payments; using Nop.Data; using Nop.Plugin.Misc.FruitBankPlugin.Domains.DataLayer; namespace Nop.Plugin.Misc.FruitBankPlugin.Services; public class CustomerCreditService : ICustomerCreditService { private readonly CustomerCreditDbTable _customerCreditDbTable; private readonly IRepository _orderRepository; public CustomerCreditService( CustomerCreditDbTable customerCreditDbTable, IRepository orderRepository) { _customerCreditDbTable = customerCreditDbTable; _orderRepository = orderRepository; } public Task GetByCustomerIdAsync(int customerId) => _customerCreditDbTable.GetByCustomerIdAsync(customerId); public async Task SaveAsync(CustomerCredit entity) { entity.UpdatedOnUtc = DateTime.UtcNow; if (entity.Id <= 0) { entity.CreatedOnUtc = DateTime.UtcNow; await _customerCreditDbTable.InsertAsync(entity); } else { await _customerCreditDbTable.UpdateAsync(entity); } } public Task DeleteAsync(CustomerCredit entity) => _customerCreditDbTable.DeleteAsync(entity); public async Task GetOutstandingBalanceAsync(int customerId) { return await _orderRepository.Table .Where(o => o.CustomerId == customerId && o.OrderStatusId != (int)OrderStatus.Cancelled && (o.PaymentStatusId == (int)PaymentStatus.Pending || o.PaymentStatusId == (int)PaymentStatus.PartiallyRefunded)) .SumAsync(o => (decimal?)o.OrderTotal) ?? 0m; } public async Task GetRemainingCreditAsync(int customerId) { var credit = await GetByCustomerIdAsync(customerId); if (credit == null) return null; var outstanding = await GetOutstandingBalanceAsync(customerId); return credit.CreditLimit - outstanding; } public async Task IsOrderAllowedAsync(int customerId, decimal newOrderTotal) { var credit = await GetByCustomerIdAsync(customerId); if (credit == null) return true; var outstanding = await GetOutstandingBalanceAsync(customerId); return outstanding + newOrderTotal <= credit.CreditLimit; } }