using Nop.Core; using Nop.Core.Domain.Customers; using Nop.Core.Domain.Orders; using Nop.Core.Events; using Nop.Data; using Nop.Services.Customers; namespace Nop.Services.Orders; /// /// Gift card service /// public partial class GiftCardService : IGiftCardService { #region Fields protected readonly ICustomerService _customerService; protected readonly IEventPublisher _eventPublisher; protected readonly IRepository _giftCardRepository; protected readonly IRepository _giftCardUsageHistoryRepository; protected readonly IRepository _orderItemRepository; #endregion #region Ctor public GiftCardService(ICustomerService customerService, IEventPublisher eventPublisher, IRepository giftCardRepository, IRepository giftCardUsageHistoryRepository, IRepository orderItemRepository) { _customerService = customerService; _eventPublisher = eventPublisher; _giftCardRepository = giftCardRepository; _giftCardUsageHistoryRepository = giftCardUsageHistoryRepository; _orderItemRepository = orderItemRepository; } #endregion #region Methods /// /// Deletes a gift card /// /// Gift card /// A task that represents the asynchronous operation public virtual async Task DeleteGiftCardAsync(GiftCard giftCard) { await _giftCardRepository.DeleteAsync(giftCard); } /// /// Gets a gift card /// /// Gift card identifier /// /// A task that represents the asynchronous operation /// The task result contains the gift card entry /// public virtual async Task GetGiftCardByIdAsync(int giftCardId) { return await _giftCardRepository.GetByIdAsync(giftCardId, cache => default); } /// /// Gets all gift cards /// /// Associated order ID; null to load all records /// The order ID in which the gift card was used; null to load all records /// Created date from (UTC); null to load all records /// Created date to (UTC); null to load all records /// Value indicating whether gift card is activated; null to load all records /// Gift card coupon code; null to load all records /// Recipient name; null to load all records /// Page index /// Page size /// /// A task that represents the asynchronous operation /// The task result contains the gift cards /// public virtual async Task> GetAllGiftCardsAsync(int? purchasedWithOrderId = null, int? usedWithOrderId = null, DateTime? createdFromUtc = null, DateTime? createdToUtc = null, bool? isGiftCardActivated = null, string giftCardCouponCode = null, string recipientName = null, int pageIndex = 0, int pageSize = int.MaxValue) { var giftCards = await _giftCardRepository.GetAllPagedAsync(query => { if (purchasedWithOrderId.HasValue) { query = from gc in query join oi in _orderItemRepository.Table on gc.PurchasedWithOrderItemId equals oi.Id where oi.OrderId == purchasedWithOrderId.Value select gc; } if (usedWithOrderId.HasValue) query = from gc in query join gcuh in _giftCardUsageHistoryRepository.Table on gc.Id equals gcuh.GiftCardId where gcuh.UsedWithOrderId == usedWithOrderId select gc; if (createdFromUtc.HasValue) query = query.Where(gc => createdFromUtc.Value <= gc.CreatedOnUtc); if (createdToUtc.HasValue) query = query.Where(gc => createdToUtc.Value >= gc.CreatedOnUtc); if (isGiftCardActivated.HasValue) query = query.Where(gc => gc.IsGiftCardActivated == isGiftCardActivated.Value); if (!string.IsNullOrEmpty(giftCardCouponCode)) query = query.Where(gc => gc.GiftCardCouponCode == giftCardCouponCode); if (!string.IsNullOrWhiteSpace(recipientName)) query = query.Where(c => c.RecipientName.Contains(recipientName)); query = query.OrderByDescending(gc => gc.CreatedOnUtc); return query; }, pageIndex, pageSize); return giftCards; } /// /// Inserts a gift card /// /// Gift card /// A task that represents the asynchronous operation public virtual async Task InsertGiftCardAsync(GiftCard giftCard) { await _giftCardRepository.InsertAsync(giftCard); } /// /// Updates the gift card /// /// Gift card /// A task that represents the asynchronous operation public virtual async Task UpdateGiftCardAsync(GiftCard giftCard) { await _giftCardRepository.UpdateAsync(giftCard); } /// /// Gets gift cards by 'PurchasedWithOrderItemId' /// /// Purchased with order item identifier /// /// A task that represents the asynchronous operation /// The task result contains the gift card entries /// public virtual async Task> GetGiftCardsByPurchasedWithOrderItemIdAsync(int purchasedWithOrderItemId) { if (purchasedWithOrderItemId == 0) return new List(); var query = _giftCardRepository.Table; query = query.Where(gc => gc.PurchasedWithOrderItemId.HasValue && gc.PurchasedWithOrderItemId.Value == purchasedWithOrderItemId); query = query.OrderBy(gc => gc.Id); var giftCards = await query.ToListAsync(); return giftCards; } /// /// Get active gift cards that are applied by a customer /// /// Customer /// /// A task that represents the asynchronous operation /// The task result contains the active gift cards /// public virtual async Task> GetActiveGiftCardsAppliedByCustomerAsync(Customer customer) { var result = new List(); if (customer == null) return result; var couponCodes = await _customerService.ParseAppliedGiftCardCouponCodesAsync(customer); foreach (var couponCode in couponCodes) { var giftCards = await GetAllGiftCardsAsync(isGiftCardActivated: true, giftCardCouponCode: couponCode); foreach (var gc in giftCards) if (await IsGiftCardValidAsync(gc)) result.Add(gc); } return result; } /// /// Generate new gift card code /// /// Result public virtual string GenerateGiftCardCode() { var length = 13; var result = Guid.NewGuid().ToString(); if (result.Length > length) result = result[0..length]; return result; } /// /// Delete gift card usage history /// /// Order /// A task that represents the asynchronous operation public virtual async Task DeleteGiftCardUsageHistoryAsync(Order order) { var giftCardUsageHistory = await GetGiftCardUsageHistoryAsync(order); await _giftCardUsageHistoryRepository.DeleteAsync(giftCardUsageHistory); var query = _giftCardRepository.Table; var giftCardIds = giftCardUsageHistory.Select(gcuh => gcuh.GiftCardId).ToArray(); var giftCards = await query.Where(bp => giftCardIds.Contains(bp.Id)).ToListAsync(); //event notification foreach (var giftCard in giftCards) await _eventPublisher.EntityUpdatedAsync(giftCard); } /// /// Gets a gift card remaining amount /// /// /// A task that represents the asynchronous operation /// The task result contains the gift card remaining amount /// public virtual async Task GetGiftCardRemainingAmountAsync(GiftCard giftCard) { ArgumentNullException.ThrowIfNull(giftCard); var result = giftCard.Amount; foreach (var gcuh in await GetGiftCardUsageHistoryAsync(giftCard)) result -= gcuh.UsedValue; if (result < decimal.Zero) result = decimal.Zero; return result; } /// /// Gets a gift card usage history entries /// /// Gift card /// /// A task that represents the asynchronous operation /// The task result contains the result /// public virtual async Task> GetGiftCardUsageHistoryAsync(GiftCard giftCard) { ArgumentNullException.ThrowIfNull(giftCard); return await _giftCardUsageHistoryRepository.Table .Where(gcuh => gcuh.GiftCardId == giftCard.Id) .ToListAsync(); } /// /// Gets a gift card usage history entries /// /// Order /// /// A task that represents the asynchronous operation /// The task result contains the result /// public virtual async Task> GetGiftCardUsageHistoryAsync(Order order) { ArgumentNullException.ThrowIfNull(order); return await _giftCardUsageHistoryRepository.Table .Where(gcuh => gcuh.UsedWithOrderId == order.Id) .ToListAsync(); } /// /// Inserts a gift card usage history entry /// /// Gift card usage history entry /// A task that represents the asynchronous operation public virtual async Task InsertGiftCardUsageHistoryAsync(GiftCardUsageHistory giftCardUsageHistory) { await _giftCardUsageHistoryRepository.InsertAsync(giftCardUsageHistory); } /// /// Is gift card valid /// /// Gift card /// /// A task that represents the asynchronous operation /// The task result contains the result /// public virtual async Task IsGiftCardValidAsync(GiftCard giftCard) { ArgumentNullException.ThrowIfNull(giftCard); if (!giftCard.IsGiftCardActivated) return false; var remainingAmount = await GetGiftCardRemainingAmountAsync(giftCard); if (remainingAmount > decimal.Zero) return true; return false; } #endregion }