using GB5Shared.DTO.Framework.Login; using GB5Shared.DTO.ReportOrchestration; using GB5Shared.Enums.ReportOrchestration; using System.Reflection; namespace FrameworkBLL.ReportOrchestration { /// /// Fluent builder for ReportExecutionContext. /// Obtained via IQueryOrchestrator.ForStandardReport / ForAnalysisReport. /// internal sealed class ReportContextBuilder : IReportContextBuilder { private readonly LoginDTO _loginDTO; private readonly int _reportId; private readonly int _analysisId; private readonly int _viewId; private readonly ReportCallType _callType; private readonly Dictionary _parameters = new(); private ExportFormat _format = ExportFormat.Grid; private DateTime? _fromDate; private DateTime? _toDate; private CancellationToken _ct = CancellationToken.None; private DataSourceType? _dataSourceOverride; internal ReportContextBuilder( LoginDTO loginDTO, int reportId, int analysisId, int viewId, ReportCallType callType) { _loginDTO = loginDTO; _reportId = reportId; _analysisId = analysisId; _viewId = viewId; _callType = callType; } public IReportContextBuilder WithParameters(object parameters) { if (parameters is Dictionary dict) { foreach (var kvp in dict) _parameters[kvp.Key] = kvp.Value; } else { // Reflect properties of anonymous objects / DTOs foreach (var prop in parameters.GetType() .GetProperties(BindingFlags.Public | BindingFlags.Instance)) { _parameters[prop.Name] = prop.GetValue(parameters); } } return this; } public IReportContextBuilder WithFormat(ExportFormat format) { _format = format; return this; } public IReportContextBuilder WithDateRange( string fromDateKey = "FromDate", string toDateKey = "ToDate") { if (_parameters.TryGetValue(fromDateKey, out var rawFrom) && rawFrom is not null) { if (DateTime.TryParse(rawFrom.ToString(), out var from)) _fromDate = from; } if (_parameters.TryGetValue(toDateKey, out var rawTo) && rawTo is not null) { if (DateTime.TryParse(rawTo.ToString(), out var to)) _toDate = to; } return this; } public IReportContextBuilder WithCancellation(CancellationToken cancellationToken) { _ct = cancellationToken; return this; } public IReportContextBuilder WithDataSourceOverride(DataSourceType dataSource) { _dataSourceOverride = dataSource; return this; } public ReportExecutionContext Build() { var ctx = new ReportExecutionContext { LoginDTO = _loginDTO, ReportId = _reportId, AnalysisId = _analysisId, ReportViewId = _viewId, CallType = _callType, Parameters = new Dictionary(_parameters), RequestedFormat = _format, FromDate = _fromDate, ToDate = _toDate, CancellationToken = _ct }; if (_dataSourceOverride.HasValue) ctx.ResolvedDataSource = _dataSourceOverride.Value; return ctx; } } }