using GB5Shared.DTO.Framework.AutoNumber; using GB5Shared.DTO.Framework.Login; using GB5Shared.GenerateAutoNumber; using GB5Shared.Resource.Response; using GB5Shared.Validation; using System.ComponentModel.DataAnnotations; using System.Text.Json; using TMSDAL.CustomCode.EvaluationResponse; using TMSDAL.DTO.Evaluation; using TMSDAL.DTO.EvaluationInstance; using TMSDAL.DTO.EvaluationResponse; namespace TMSBLL.EvaluationResponse { public class EvaluationResponseBLL : IEvaluationResponseBLL { private readonly IEvaluationResponseDAL _EvaluationResponseDAL; private readonly AutoNumber _AutoNumber; private readonly IValidation _Validation; public EvaluationResponseBLL( IEvaluationResponseDAL evaluationResponseDAL, AutoNumber autoNumber, IValidation validation) { _EvaluationResponseDAL = evaluationResponseDAL; _AutoNumber = autoNumber; _Validation = validation; } public async Task GetEvaluationResponse(int evaluationResponseId, LoginDTO loginDTO) { try { return await _EvaluationResponseDAL.GetEvaluationResponse(evaluationResponseId, loginDTO); } catch (Exception) { throw; } } public async Task GetEvaluationResponseList(int evaluationInstanceId, LoginDTO loginDTO) { try { return await _EvaluationResponseDAL.GetEvaluationResponseList(evaluationInstanceId, loginDTO); } catch (Exception) { throw; } } /// /// Submits a response and automatically marks the instance as Completed (EvalStatus = 2). /// Responses are immutable — no update after submission. /// public async Task SubmitEvaluationResponse(EvaluationResponseDTO dto, LoginDTO loginDTO) { if (dto == null) throw new ArgumentNullException(nameof(dto)); AutoNumberDTO? autoNumberDTO = null; try { await _Validation.NotEmpty(dto.EvaluationInstanceId.ToString(), nameof(dto.EvaluationInstanceId)); await _Validation.NotEmpty(dto.RespondentId.ToString(), nameof(dto.RespondentId)); await _Validation.NotEmpty(dto.ResponseDataJson, nameof(dto.ResponseDataJson)); dto.TenantId = loginDTO.ClientId; dto.ModifiedById = loginDTO.UserId; dto.ModifiedOn = DateTime.UtcNow; dto.SubmittedOn = DateTime.UtcNow; dto.CreatedById = loginDTO.UserId; dto.CreatedOn = DateTime.UtcNow; autoNumberDTO = await _AutoNumber.GetAutoNumber(1, "EVALUATIONRESPONSE", loginDTO); dto.EvaluationResponseId = autoNumberDTO.StartNumber; // Step 1: Save response await _EvaluationResponseDAL.SaveEvaluationResponse(dto, loginDTO); // Step 2: Mark instance as Completed var instanceUpdate = new EvaluationInstanceDTO { EvaluationInstanceId = dto.EvaluationInstanceId, EvalStatus = 2, // Completed CompletedAt = DateTime.UtcNow, TenantId = loginDTO.ClientId, ModifiedById = loginDTO.UserId, ModifiedOn = DateTime.UtcNow }; await _EvaluationResponseDAL.UpdateEvaluationInstanceStatus(instanceUpdate, loginDTO); var savedJson = await _EvaluationResponseDAL.GetEvaluationResponse(dto.EvaluationResponseId, loginDTO); var saved = JsonSerializer.Deserialize( savedJson, new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); return string.Format(SuccessResponse.SaveSuccessWithName, saved?.RespondentName); } catch (ValidationException vex) { throw new Exception(vex.Message); } catch (Exception) { if (autoNumberDTO != null && dto.EvaluationResponseId > 0) await _AutoNumber.RollbackAutoNumber("EVALUATIONRESPONSE", dto.EvaluationResponseId, loginDTO); throw; } } } }