using System.Runtime.CompilerServices; using GB5Shared.DTO.Framework.Criteria; using GB5Shared.DTO.Framework.Login; using GB5Shared.QueryExecutor; using GB5Shared.Telemetry; using RecruitmentDAL.CustomeCode.Reports.PipelineConversionFunnel; using RecruitmentDAL.DTO.Reports; namespace RecruitmentBLL.Reports.PipelineConversionFunnel { // Phase 5 analytics — pipeline-conversion (funnel) report. CriteriaDTO.Id doubles as an // optional SelectionProcessTemplateId filter (same "0/<=0 = unset" convention as // ApplicationCycleTimeBLL's JobRequisitionId filter) — a caller who wants every template's // funnel for the tenant simply omits it / leaves it 0. public class PipelineConversionFunnelBLL : IPipelineConversionFunnelBLL { private const int DEFAULT_MAX_RESULT_CAP = 500; private readonly IPipelineConversionFunnelDAL _dal; public PipelineConversionFunnelBLL(IPipelineConversionFunnelDAL dal) { _dal = dal; } public async Task> GetPipelineConversionFunnel( int firstNumber, int maxResult, CriteriaDTO? criteriaDTO, LoginDTO login, CancellationToken ct) { try { var selectionProcessTemplateId = ResolveTemplateIdFilter(criteriaDTO); var cappedMaxResult = maxResult > 0 ? Math.Min(maxResult, DEFAULT_MAX_RESULT_CAP) : DEFAULT_MAX_RESULT_CAP; GB5Trace.Step("query-pipeline-conversion-funnel", new { firstNumber, cappedMaxResult, selectionProcessTemplateId }); return await _dal.GetPipelineConversionFunnel(firstNumber, cappedMaxResult, selectionProcessTemplateId, login, ct).ConfigureAwait(false); } catch (Exception ex) { GB5Trace.MarkFailed("pipeline-conversion-funnel-failed", ex); throw; } } public async IAsyncEnumerable GetPipelineConversionFunnelStream( int firstNumber, int maxResult, CriteriaDTO? criteriaDTO, LoginDTO login, [EnumeratorCancellation] CancellationToken ct) { var selectionProcessTemplateId = ResolveTemplateIdFilter(criteriaDTO); GB5Trace.Step("stream-pipeline-conversion-funnel", new { firstNumber, maxResult, selectionProcessTemplateId }); await foreach (var row in _dal.GetPipelineConversionFunnelStream(selectionProcessTemplateId, login, ct).ConfigureAwait(false)) yield return row; } private static int? ResolveTemplateIdFilter(CriteriaDTO? criteriaDTO) => criteriaDTO != null && criteriaDTO.Id > 0 ? criteriaDTO.Id : null; } }