using System.Text.Json; using FLSBLL.Session; using FLSDAL.CustomCode.Survey; using FLSDAL.DTO.Session; using FLSDAL.DTO.Survey; using GB5Shared.DTO.Framework.Login; using GB5Shared.GenerateAutoNumber; using GB5Shared.Resource.Response; using GB5Shared.Telemetry; using Microsoft.Extensions.Logging; namespace FLSBLL.Survey; public class SurveyAnswerBLL : ISurveyAnswerBLL { private readonly ISurveyAnswerDAL _answerDal; private readonly ISurveySummaryDAL _summaryDal; private readonly ISurveySummaryBLL _summaryBll; private readonly IFlsSessionBLL _sessionBll; private readonly AutoNumber _autoNumber; private readonly ILogger _logger; public SurveyAnswerBLL( ISurveyAnswerDAL answerDal, ISurveySummaryDAL summaryDal, ISurveySummaryBLL summaryBll, IFlsSessionBLL sessionBll, AutoNumber autoNumber, ILogger logger) { _answerDal = answerDal; _summaryDal = summaryDal; _summaryBll = summaryBll; _sessionBll = sessionBll; _autoNumber = autoNumber; _logger = logger; } public async Task SaveDraftAnswersAsync( SaveSurveyDraftRequest req, FlsSessionContextDto ctx, LoginDTO login, CancellationToken ct) { try { GB5Trace.Step("save-draft-survey-answers", new { req.FlsSessionId, count = req.Answers.Count }); var answerIds = await AllocateAnswerIdsAsync(req.Answers.Count, login, ct).ConfigureAwait(false); await _answerDal.UpsertAnswersAsync(req.FlsSessionId, req.Answers, answerIds, isDraft: true, login, ct) .ConfigureAwait(false); return SuccessResponse.UpdateSuccess; } catch (Exception ex) { GB5Trace.MarkFailed("save-draft-survey-answers-failed", ex); _logger.LogError(ex, "SaveDraftAnswers failed for session {Id}", req.FlsSessionId); throw; } } public async Task SubmitAnswersAsync( SubmitSurveyRequest req, FlsSessionContextDto ctx, LoginDTO login, CancellationToken ct) { try { GB5Trace.Step("validate-survey-answers", new { req.FlsSessionId }); if (ctx.InstrumentConfigId == -1) return "No survey instrument linked to this session."; var answerIds = await AllocateAnswerIdsAsync(req.Answers.Count, login, ct).ConfigureAwait(false); GB5Trace.Step("save-survey-answers", new { req.FlsSessionId, ctx.InstrumentConfigId }); await _answerDal.UpsertAnswersAsync(req.FlsSessionId, req.Answers, answerIds, isDraft: false, login, ct) .ConfigureAwait(false); GB5Trace.Step("submit-fls-session-from-survey", new { req.FlsSessionId }); await _sessionBll.SubmitAsync(req.FlsSessionId, login, ct).ConfigureAwait(false); GB5Trace.Step("update-survey-summary-from-submit", new { ctx.InstrumentConfigId, ctx.FlsInstanceId, ctx.GroupId }); await _summaryBll.UpdateSummaryAsync(ctx.InstrumentConfigId, ctx.FlsInstanceId, ctx.GroupId, login, ct) .ConfigureAwait(false); return SuccessResponse.UpdateSuccess; } catch (Exception ex) { GB5Trace.MarkFailed("submit-survey-answers-failed", ex); _logger.LogError(ex, "SubmitAnswers failed for session {Id}", req.FlsSessionId); throw; } } private async Task> AllocateAnswerIdsAsync(int count, LoginDTO login, CancellationToken ct) { if (count == 0) return new List(); var autoNum = await _autoNumber.GetNumberAsync(count, "SURVEYANSWER", login).ConfigureAwait(false); return Enumerable.Range(autoNum.StartNumber, count).ToList(); } public async Task GetAnswersAsync(int flsSessionId, LoginDTO login, CancellationToken ct) { try { GB5Trace.Step("get-survey-answers", new { flsSessionId }); var answers = await _answerDal.GetBySessionAsync(flsSessionId, login, ct).ConfigureAwait(false); return JsonSerializer.Serialize(answers); } catch (Exception ex) { GB5Trace.MarkFailed("get-survey-answers-failed", ex); _logger.LogError(ex, "GetAnswers failed for session {Id}", flsSessionId); throw; } } }