using MediatR; using TakeoutSaaS.Application.App.Finance.Cost.Commands; using TakeoutSaaS.Application.App.Finance.Cost.Dto; using TakeoutSaaS.Domain.Finance.Models; using TakeoutSaaS.Domain.Finance.Repositories; using TakeoutSaaS.Shared.Abstractions.Tenancy; namespace TakeoutSaaS.Application.App.Finance.Cost.Handlers; /// /// 成本录入保存处理器。 /// public sealed class SaveFinanceCostEntryCommandHandler( IFinanceCostRepository financeCostRepository, ITenantProvider tenantProvider) : IRequestHandler { /// public async Task Handle( SaveFinanceCostEntryCommand request, CancellationToken cancellationToken) { // 1. 归一化入参并组装仓储快照模型。 var tenantId = tenantProvider.GetCurrentTenantId(); var normalizedMonth = FinanceCostMapping.NormalizeMonthStart(request.CostMonth); var categories = request.Categories.Select(category => new FinanceCostCategorySnapshot { Category = category.Category, TotalAmount = FinanceCostMapping.RoundAmount(category.TotalAmount), Items = (category.Items ?? []) .Select(item => new FinanceCostDetailItemSnapshot { ItemId = item.ItemId, ItemName = item.ItemName, Amount = FinanceCostMapping.RoundAmount(item.Amount), Quantity = item.Quantity.HasValue ? FinanceCostMapping.RoundAmount(item.Quantity.Value) : null, UnitPrice = item.UnitPrice.HasValue ? FinanceCostMapping.RoundAmount(item.UnitPrice.Value) : null, SortOrder = item.SortOrder }) .ToList() }).ToList(); // 2. 持久化保存并重新查询最新快照。 await financeCostRepository.SaveMonthSnapshotAsync( tenantId, request.Dimension, request.StoreId, normalizedMonth, categories, cancellationToken); var snapshot = await financeCostRepository.GetMonthSnapshotAsync( tenantId, request.Dimension, request.StoreId, normalizedMonth, cancellationToken); // 3. 映射为页面 DTO 返回。 return FinanceCostMapping.ToEntryDto(snapshot); } }