using System.Globalization; using Nop.Core; using Nop.Core.Domain.Orders; using Nop.Services.Customers; using Nop.Services.Helpers; using Nop.Services.Localization; using Nop.Services.Orders; using Nop.Services.Payments; using Nop.Web.Areas.Admin.Infrastructure.Mapper.Extensions; using Nop.Web.Areas.Admin.Models.Orders; using Nop.Web.Framework.Models.Extensions; namespace Nop.Web.Areas.Admin.Factories; /// /// Represents the recurring payment model factory implementation /// public partial class RecurringPaymentModelFactory : IRecurringPaymentModelFactory { #region Fields protected readonly IDateTimeHelper _dateTimeHelper; protected readonly ICustomerService _customerService; protected readonly ILocalizationService _localizationService; protected readonly IOrderProcessingService _orderProcessingService; protected readonly IOrderService _orderService; protected readonly IPaymentService _paymentService; protected readonly IWorkContext _workContext; #endregion #region Ctor public RecurringPaymentModelFactory(IDateTimeHelper dateTimeHelper, ICustomerService customerService, ILocalizationService localizationService, IOrderProcessingService orderProcessingService, IOrderService orderService, IPaymentService paymentService, IWorkContext workContext) { _dateTimeHelper = dateTimeHelper; _customerService = customerService; _localizationService = localizationService; _orderProcessingService = orderProcessingService; _orderService = orderService; _paymentService = paymentService; _workContext = workContext; } #endregion #region Utilities /// /// Prepare recurring payment history search model /// /// Recurring payment history search model /// Recurring payment /// Recurring payment history search model protected virtual RecurringPaymentHistorySearchModel PrepareRecurringPaymentHistorySearchModel(RecurringPaymentHistorySearchModel searchModel, RecurringPayment recurringPayment) { ArgumentNullException.ThrowIfNull(searchModel); ArgumentNullException.ThrowIfNull(recurringPayment); searchModel.RecurringPaymentId = recurringPayment.Id; //prepare page parameters searchModel.SetGridPageSize(); return searchModel; } #endregion #region Methods /// /// Prepare recurring payment search model /// /// Recurring payment search model /// /// A task that represents the asynchronous operation /// The task result contains the recurring payment search model /// public virtual Task PrepareRecurringPaymentSearchModelAsync(RecurringPaymentSearchModel searchModel) { ArgumentNullException.ThrowIfNull(searchModel); //prepare page parameters searchModel.SetGridPageSize(); return Task.FromResult(searchModel); } /// /// Prepare paged recurring payment list model /// /// Recurring payment search model /// /// A task that represents the asynchronous operation /// The task result contains the recurring payment list model /// public virtual async Task PrepareRecurringPaymentListModelAsync(RecurringPaymentSearchModel searchModel) { ArgumentNullException.ThrowIfNull(searchModel); //get recurringPayments var recurringPayments = await _orderService.SearchRecurringPaymentsAsync(showHidden: true, pageIndex: searchModel.Page - 1, pageSize: searchModel.PageSize); //prepare list model var model = await new RecurringPaymentListModel().PrepareToGridAsync(searchModel, recurringPayments, () => { return recurringPayments.SelectAwait(async recurringPayment => { //fill in model values from the entity var recurringPaymentModel = recurringPayment.ToModel(); var order = await _orderService.GetOrderByIdAsync(recurringPayment.InitialOrderId); var customer = await _customerService.GetCustomerByIdAsync(order.CustomerId); //convert dates to the user time if ((await _orderProcessingService.GetNextPaymentDateAsync(recurringPayment)) is DateTime nextPaymentDate) { recurringPaymentModel.NextPaymentDate = (await _dateTimeHelper .ConvertToUserTimeAsync(nextPaymentDate, DateTimeKind.Utc)).ToString(CultureInfo.InvariantCulture); recurringPaymentModel.CyclesRemaining = await _orderProcessingService.GetCyclesRemainingAsync(recurringPayment); } recurringPaymentModel.StartDate = (await _dateTimeHelper .ConvertToUserTimeAsync(recurringPayment.StartDateUtc, DateTimeKind.Utc)).ToString(CultureInfo.InvariantCulture); //fill in additional values (not existing in the entity) recurringPaymentModel.CustomerId = customer.Id; recurringPaymentModel.InitialOrderId = order.Id; recurringPaymentModel.CyclePeriodStr = await _localizationService.GetLocalizedEnumAsync(recurringPayment.CyclePeriod); recurringPaymentModel.CustomerEmail = (await _customerService.IsRegisteredAsync(customer)) ? customer.Email : await _localizationService.GetResourceAsync("Admin.Customers.Guest"); return recurringPaymentModel; }); }); return model; } /// /// Prepare recurring payment model /// /// Recurring payment model /// Recurring payment /// Whether to exclude populating of some properties of model /// /// A task that represents the asynchronous operation /// The task result contains the recurring payment model /// public virtual async Task PrepareRecurringPaymentModelAsync(RecurringPaymentModel model, RecurringPayment recurringPayment, bool excludeProperties = false) { if (recurringPayment == null) return model; //fill in model values from the entity if (model == null) model = recurringPayment.ToModel(); var order = await _orderService.GetOrderByIdAsync(recurringPayment.InitialOrderId); var customer = await _customerService.GetCustomerByIdAsync(order.CustomerId); //convert dates to the user time if (await _orderProcessingService.GetNextPaymentDateAsync(recurringPayment) is DateTime nextPaymentDate) { model.NextPaymentDate = (await _dateTimeHelper.ConvertToUserTimeAsync(nextPaymentDate, DateTimeKind.Utc)).ToString(CultureInfo.InvariantCulture); model.CyclesRemaining = await _orderProcessingService.GetCyclesRemainingAsync(recurringPayment); } model.StartDate = (await _dateTimeHelper.ConvertToUserTimeAsync(recurringPayment.StartDateUtc, DateTimeKind.Utc)).ToString(CultureInfo.InvariantCulture); model.CustomerId = customer.Id; model.InitialOrderId = order.Id; model.CustomerEmail = await _customerService.IsRegisteredAsync(customer) ? customer.Email : await _localizationService.GetResourceAsync("Admin.Customers.Guest"); model.PaymentType = await _localizationService.GetLocalizedEnumAsync(await _paymentService .GetRecurringPaymentTypeAsync(order.PaymentMethodSystemName)); model.CanCancelRecurringPayment = await _orderProcessingService.CanCancelRecurringPaymentAsync(await _workContext.GetCurrentCustomerAsync(), recurringPayment); //prepare nested search model PrepareRecurringPaymentHistorySearchModel(model.RecurringPaymentHistorySearchModel, recurringPayment); return model; } /// /// Prepare paged recurring payment history list model /// /// Recurring payment history search model /// Recurring payment /// /// A task that represents the asynchronous operation /// The task result contains the recurring payment history list model /// public virtual async Task PrepareRecurringPaymentHistoryListModelAsync(RecurringPaymentHistorySearchModel searchModel, RecurringPayment recurringPayment) { ArgumentNullException.ThrowIfNull(searchModel); ArgumentNullException.ThrowIfNull(recurringPayment); //get recurring payments history var recurringPayments = (await _orderService.GetRecurringPaymentHistoryAsync(recurringPayment)) .OrderBy(historyEntry => historyEntry.CreatedOnUtc).ToList() .ToPagedList(searchModel); //prepare list model var model = await new RecurringPaymentHistoryListModel().PrepareToGridAsync(searchModel, recurringPayments, () => { return recurringPayments.SelectAwait(async historyEntry => { //fill in model values from the entity var historyModel = historyEntry.ToModel(); //convert dates to the user time historyModel.CreatedOn = await _dateTimeHelper.ConvertToUserTimeAsync(historyEntry.CreatedOnUtc, DateTimeKind.Utc); //fill in additional values (not existing in the entity) var order = await _orderService.GetOrderByIdAsync(historyEntry.OrderId); if (order == null) return historyModel; historyModel.OrderStatus = await _localizationService.GetLocalizedEnumAsync(order.OrderStatus); historyModel.PaymentStatus = await _localizationService.GetLocalizedEnumAsync(order.PaymentStatus); historyModel.ShippingStatus = await _localizationService.GetLocalizedEnumAsync(order.ShippingStatus); historyModel.CustomOrderNumber = order.CustomOrderNumber; return historyModel; }); }); return model; } #endregion }