using Fake.DependencyInjection; using Oms.Application.Dtos.Marketing; using Oms.Domain.CustomersAggregate.Repositories; using Oms.Domain.MarketingAggregate.Entities; using Oms.Domain.MarketingAggregate.Repositories; using Oms.Domain.OrdersAggregate.Entities; namespace Oms.Application.Shared; /// /// 订单营销快照写入与查价叠加。 /// public class MarketingOrderHelper : IScopedDependency { private readonly ICustomerRepository _customerRepository; private readonly IMemberLevelRepository _memberLevelRepository; private readonly MarketingCouponManager _couponManager; public MarketingOrderHelper( ICustomerRepository customerRepository, IMemberLevelRepository memberLevelRepository, MarketingCouponManager couponManager) { _customerRepository = customerRepository; _memberLevelRepository = memberLevelRepository; _couponManager = couponManager; } public async Task BuildBreakdownAsync( int? customerId, decimal receivableSubtotal, int? couponInstanceId, CancellationToken cancellationToken = default) { if (!customerId.HasValue || customerId.Value <= 0) { return MarketingBillingCalculator.Calculate(receivableSubtotal, 0M, null, null, null, null); } var sessionCustomer = await _customerRepository.FirstOrDefaultAsync(x => x.Id == customerId.Value, cancellationToken); if (sessionCustomer == null) { return MarketingBillingCalculator.Calculate(receivableSubtotal, 0M, null, null, null, null); } var mainCustomer = await MarketingCustomerHelper.ResolveMarketingMainCustomerAsync(_customerRepository, sessionCustomer, cancellationToken); var mainCustomerId = mainCustomer.Id; MemberLevel? level = null; if (mainCustomer.MemberLevelId.HasValue) { level = await _memberLevelRepository.FirstOrDefaultAsync(x => x.Id == mainCustomer.MemberLevelId.Value, cancellationToken); } var priceTierKey = level?.PriceTierKey ?? MarketingCustomerHelper.MapCustomerGroupToPriceTierKey(mainCustomer.CustomerGroup); var couponInput = await _couponManager.ResolveCouponDiscountInputAsync(couponInstanceId, mainCustomerId, cancellationToken); return MarketingBillingCalculator.Calculate( receivableSubtotal, level?.ExtraDiscountRate ?? 0M, level?.Id, level?.LevelName, priceTierKey, couponInput); } public void ApplySnapshotToOrder(Order order, MarketingPriceBreakdown breakdown, int? couponInstanceId) { order.MemberLevelId = breakdown.MemberLevelId; order.PriceTierKey = breakdown.PriceTierKey; order.ReceivableSubtotal = breakdown.ReceivableSubtotal; order.LevelDiscountAmount = breakdown.LevelDiscountAmount; order.CouponInstanceId = couponInstanceId ?? breakdown.CouponInstanceId; order.CouponDiscountAmount = breakdown.CouponDiscountAmount; order.PayableAmount = breakdown.PayableAmount; } public async Task> BuildAvailableCouponsAsync( int? customerId, decimal? amountAfterLevel, CancellationToken cancellationToken = default) { if (!customerId.HasValue || customerId.Value <= 0) { return []; } var sessionCustomer = await _customerRepository.FirstOrDefaultAsync(x => x.Id == customerId.Value, cancellationToken); if (sessionCustomer == null) { return []; } var mainCustomer = await MarketingCustomerHelper.ResolveMarketingMainCustomerAsync( _customerRepository, sessionCustomer, cancellationToken); return await _couponManager.BuildAvailableCouponsAsync(mainCustomer.Id, amountAfterLevel, cancellationToken); } }