diff --git a/back/Contracts/Repositories/ISpendingGroupRepo.cs b/back/Contracts/Repositories/ISpendingGroupRepo.cs index f8f7999..54f4476 100644 --- a/back/Contracts/Repositories/ISpendingGroupRepo.cs +++ b/back/Contracts/Repositories/ISpendingGroupRepo.cs @@ -6,6 +6,7 @@ namespace Contracts.Repositories; public interface ISpendingGroupRepo { Task Get(SpendingGroupSearch search); + Task GetByPlan(SpendingPlanSearch search); Task> GetList(SpendingGroupSearch? search = null); Task Create(SpendingGroupDto spendingGroup); Task Delete(SpendingGroupSearch search); diff --git a/back/Contracts/Services/IReportOffsetFromPlanService.cs b/back/Contracts/Services/IReportOffsetFromPlanService.cs new file mode 100644 index 0000000..f9c51ed --- /dev/null +++ b/back/Contracts/Services/IReportOffsetFromPlanService.cs @@ -0,0 +1,9 @@ +using Contracts.SearchModels; +using Contracts.ViewModels; + +namespace Contracts.Services; + +public interface IReportOffsetFromPlanService +{ + public Task GetReportData(SpendingPlanSearch search); +} \ No newline at end of file diff --git a/back/Infrastructure/Repositories/SpendingGroupRepo.cs b/back/Infrastructure/Repositories/SpendingGroupRepo.cs index 6c8382a..a356914 100644 --- a/back/Infrastructure/Repositories/SpendingGroupRepo.cs +++ b/back/Infrastructure/Repositories/SpendingGroupRepo.cs @@ -54,6 +54,30 @@ public class SpendingGroupRepo : ISpendingGroupRepo return group?.ToDto(); } + public async Task GetByPlan(SpendingPlanSearch search) + { + using var context = _factory.CreateDbContext(); + var plan = await context.SpendingPlans + .FirstOrDefaultAsync(x => x.Id == search.Id); + + if (plan == null) + { + return null; + } + + var group = await context.SpendingGroups + .Where(x => x.Id == plan.SpendingGroupId) + .Include(x => x.ChangeRecords != null + ? x.ChangeRecords + .Where(cg => cg.ChangedAt >= plan.StartAt && cg.ChangedAt <= plan.EndAt) + .OrderBy(cg => cg.ChangedAt) + : null) + .LastAsync(); + group.SpendingPlans = [plan]; + + return group.ToDto(); + } + public async Task> GetList(SpendingGroupSearch? search = null) { using var context = _factory.CreateDbContext(); diff --git a/back/Services/Reports/ReportOffsetFromPlanService.cs b/back/Services/Reports/ReportOffsetFromPlanService.cs new file mode 100644 index 0000000..d2a66b6 --- /dev/null +++ b/back/Services/Reports/ReportOffsetFromPlanService.cs @@ -0,0 +1,32 @@ +using Contracts.Mappers; +using Contracts.Repositories; +using Contracts.SearchModels; +using Contracts.Services; +using Contracts.ViewModels; +using Services.Support.Exceptions; + +namespace Services.Reports; + +public class ReportOffsetFromPlanService : IReportOffsetFromPlanService +{ + private readonly ISpendingGroupRepo _spendingGroupRepo; + + public ReportOffsetFromPlanService(ISpendingGroupRepo spendingGroupRepo) + { + _spendingGroupRepo = spendingGroupRepo; + } + + public async Task GetReportData(SpendingPlanSearch search) + { + var group = await _spendingGroupRepo.GetByPlan(search); + if (group == null) + { + throw new EntityNotFoundException("Не удалось найти группу по такому плану"); + } + if (!group.ChangeRecords.Any()) + { + throw new ReportDataNotFoundException("Данные об изменении баланса отсутствуют"); + } + return group.ToView(); + } +} diff --git a/back/Services/Support/Exceptions/ReportDataNotFoundException.cs b/back/Services/Support/Exceptions/ReportDataNotFoundException.cs new file mode 100644 index 0000000..ffdd60e --- /dev/null +++ b/back/Services/Support/Exceptions/ReportDataNotFoundException.cs @@ -0,0 +1,10 @@ +namespace Services.Support.Exceptions; + +public class ReportDataNotFoundException : EntityNotFoundException +{ + public ReportDataNotFoundException(string message) + : base(message) { } + public ReportDataNotFoundException(string message, Exception innerException) + : base(message, innerException) { } + +} \ No newline at end of file