using System; using System.Collections.Generic; using System.Security.Claims; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using OnlineAssessment.Common; using OnlineAssessment.Data.EFCore; using OnlineAssessment.Domain.Models; using OnlineAssessment.Domain.ViewModels; namespace OnlineAssessment.V1.Controllers { [Authorize] [ApiVersion("1.0")] [Route("v{version:apiVersion}")] public class ExamAttemptsController : BaseController { EFCoreExamAttemptRepository _repository; string responseMessage = string.Empty; int institute_id; public ExamAttemptsController(EFCoreExamAttemptRepository repository) : base(repository) { _repository = repository; } #region ExamAttempts /// /// Get all exams /// /// /// /// /// /// /// /// /// Invalid input /// Resource is not allowed /// No Data /// Unknown error [HttpGet("{language}/Batches/{batch_id}/UpcomingExams")] [ProducesResponseType(typeof(ExamAttemptAllExamPagedModel), 200)] [Authorize(Roles = "Student")] public IActionResult GetUpcomingExamsOfTheBatch(string language, int batch_id, [FromQuery] int subject_id, [FromQuery] string sortBy, string sortOrder, [FromQuery] int? pageNumber, [FromQuery] int? pageSize) { IActionResult returnResponse = null; int user_id = Security.GetIdFromJwtToken(UserClaim.UserId, HttpContext.User.Identity as ClaimsIdentity); ExamAttemptAllExamPagedModel examListPaged = new ExamAttemptAllExamPagedModel(); int language_id = _repository.GetLanguageIdByCode(language); if (language_id <= 0) { responseMessage = _repository.GetMessageByCode(Message.InvalidInput.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.InvalidInput, responseMessage)); return returnResponse; } bool isValidBatch = _repository.isValidBatch(institute_id, batch_id, user_id); if (isValidBatch == false) { responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.NotAllowedToResource, responseMessage)); return returnResponse; } if (pageNumber == null) pageNumber = 1; if (pageSize == null) pageSize = 10; if (sortBy == null) sortBy = "DATE"; if (sortOrder == null) sortOrder = "A"; dynamic theList = _repository.GetUpcomingExamsOfTheBatch(base.InstituteId, batch_id, user_id, sortBy, sortOrder); if(theList is List && theList != null) { if (pageNumber != null && pageSize != null) { PaginatedList pList = PaginatedList.CreateAsync(theList, (int)pageNumber, (int)pageSize); examListPaged.total_count = theList.Count; examListPaged.total_pages = pList.TotalPages; examListPaged.page_index = pList.PageIndex; examListPaged.next = pList.HasNextPage; examListPaged.previous = pList.HasPreviousPage; examListPaged.exams = pList; } returnResponse = Ok(ReturnResponse.GetSuccessStatus(examListPaged)); } else if(theList is int && theList == (int)Message.NotAllowedToResource) { responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.NotAllowedToResource, responseMessage)); } else if (theList == null) { responseMessage = _repository.GetMessageByCode(Message.NoData.ToString()); returnResponse = Ok(ReturnResponse.GetFailureStatus((int)Message.NoData, responseMessage)); } else { responseMessage = _repository.GetMessageByCode(Message.Failure.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.Failure, responseMessage)); } return returnResponse; } /// /// Get all live exams /// /// /// /// /// /// /// Invalid input /// Resource is not allowed /// No Data /// Unknown error [HttpGet("{language}/Batches/{batch_id}/LiveExams")] [ProducesResponseType(typeof(ExamAttemptAllExamPagedModel), 200)] [Authorize(Roles = "Student")] public IActionResult GetLiveExams(string language, int batch_id, [FromQuery] int subject_id, [FromQuery] string sortBy, string sortOrder, [FromQuery] int? pageNumber, [FromQuery] int? pageSize) { IActionResult returnResponse; int user_id = Security.GetIdFromJwtToken(UserClaim.UserId, HttpContext.User.Identity as ClaimsIdentity); ExamAttemptAllExamPagedModel examListPaged = new ExamAttemptAllExamPagedModel(); int language_id = _repository.GetLanguageIdByCode(language); if (language_id <= 0) { responseMessage = _repository.GetMessageByCode(Message.InvalidInput.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.InvalidInput, responseMessage)); return returnResponse; } bool isValidBatch = _repository.isValidBatch(institute_id, batch_id, user_id); if (isValidBatch == false) { responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.NotAllowedToResource, responseMessage)); return returnResponse; } if (pageNumber == null) pageNumber = 1; if (pageSize == null) pageSize = 10; if (sortBy == null) sortBy = "DATE"; if (sortOrder == null) sortOrder = "D"; dynamic theList = _repository.GetLiveExamsBySubject(base.InstituteId, batch_id, user_id, subject_id, sortBy, sortOrder); if (theList is List && theList != null) { if (pageNumber != null && pageSize != null) { PaginatedList pList = PaginatedList.CreateAsync(theList, (int)pageNumber, (int)pageSize); examListPaged.total_count = theList.Count; examListPaged.total_pages = pList.TotalPages; examListPaged.page_index = pList.PageIndex; examListPaged.next = pList.HasNextPage; examListPaged.previous = pList.HasPreviousPage; examListPaged.exams = pList; } returnResponse = Ok(ReturnResponse.GetSuccessStatus(examListPaged)); } else if (theList is int && theList == (int)Message.NotAllowedToResource) { responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.NotAllowedToResource, responseMessage)); } else if(theList == null) { responseMessage = _repository.GetMessageByCode(Message.NoData.ToString()); returnResponse = Ok(ReturnResponse.GetFailureStatus((int)Message.NoData, responseMessage)); } else { responseMessage = _repository.GetMessageByCode(Message.Failure.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.Failure, responseMessage)); } return returnResponse; } /// /// Get all live exams by author (subject id = 0 means fullexam, -1 means all exam, other than that will return based on subject) /// /// /// /// /// /// /// /// Invalid input /// Resource is not allowed /// No Data /// Unknown error [HttpGet("{language}/Batches/{batch_id}/LiveAuthorExams/{author_id}")] [ProducesResponseType(typeof(ExamAttemptAllExamPagedModel), 200)] [Authorize(Roles = "Student")] public IActionResult GetLiveAuthorExams(string language, int batch_id, int author_id, [FromQuery] int subject_id, [FromQuery] string sortBy, string sortOrder, [FromQuery] int? pageNumber, [FromQuery] int? pageSize) { IActionResult returnResponse; int user_id = Security.GetIdFromJwtToken(UserClaim.UserId, HttpContext.User.Identity as ClaimsIdentity); ExamAttemptAllExamPagedModel examListPaged = new ExamAttemptAllExamPagedModel(); int language_id = _repository.GetLanguageIdByCode(language); if (language_id <= 0) { responseMessage = _repository.GetMessageByCode(Message.InvalidInput.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.InvalidInput, responseMessage)); return returnResponse; } bool isValidBatch = _repository.isValidBatch(institute_id, batch_id, user_id); if (isValidBatch == false) { responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.NotAllowedToResource, responseMessage)); return returnResponse; } if (pageNumber == null) pageNumber = 1; if (pageSize == null) pageSize = 10; if (sortBy == null) sortBy = "DATE"; if (sortOrder == null) sortOrder = "D"; dynamic theList = _repository.GetLiveExamsByAuthor(base.InstituteId, batch_id, user_id, author_id, subject_id, sortBy, sortOrder); if (theList is List && theList != null) { if (pageNumber != null && pageSize != null) { PaginatedList pList = PaginatedList.CreateAsync(theList, (int)pageNumber, (int)pageSize); examListPaged.total_count = theList.Count; examListPaged.total_pages = pList.TotalPages; examListPaged.page_index = pList.PageIndex; examListPaged.next = pList.HasNextPage; examListPaged.previous = pList.HasPreviousPage; examListPaged.exams = pList; } returnResponse = Ok(ReturnResponse.GetSuccessStatus(examListPaged)); } else if (theList is int && theList == (int)Message.NotAllowedToResource) { responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.NotAllowedToResource, responseMessage)); } else if(theList == null) { responseMessage = _repository.GetMessageByCode(Message.NoData.ToString()); returnResponse = Ok(ReturnResponse.GetFailureStatus((int)Message.NoData, responseMessage)); } else { responseMessage = _repository.GetMessageByCode(Message.Failure.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.Failure, responseMessage)); } return returnResponse; } /// /// Get all attempted exams /// /// /// /// /// Invalid input /// Resource is not allowed /// No Data /// Unknown error [HttpGet("{language}/Batches/{batch_id}/AttemptedExams")] [ProducesResponseType(typeof(ExamAttemptAttemptedExamPagedModel), 200)] [Authorize(Roles = "Student")] public IActionResult GetAttemptedExams(string language, int batch_id, [FromQuery] string sortBy, string sortOrder, [FromQuery] int? pageNumber, [FromQuery] int? pageSize) { IActionResult returnResponse; int user_id = Security.GetIdFromJwtToken(UserClaim.UserId, HttpContext.User.Identity as ClaimsIdentity); ExamAttemptAttemptedExamPagedModel examListPaged = new ExamAttemptAttemptedExamPagedModel(); int language_id = _repository.GetLanguageIdByCode(language); if (language_id <= 0) { responseMessage = _repository.GetMessageByCode(Message.InvalidInput.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.InvalidInput, responseMessage)); return returnResponse; } bool isValidBatch = _repository.isValidBatch(institute_id, batch_id, user_id); if (isValidBatch == false) { responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.NotAllowedToResource, responseMessage)); return returnResponse; } if (pageNumber == null) pageNumber = 1; if (pageSize == null) pageSize = 10; if (sortBy == null) sortBy = "DATE"; if (sortOrder == null) sortOrder = "D"; dynamic theList = _repository.GetAttemptedExams(base.InstituteId, batch_id, user_id, sortBy, sortOrder); if (theList != null && theList is List) { if (pageNumber != null && pageSize != null) { PaginatedList pList = PaginatedList.CreateAsync(theList, (int)pageNumber, (int)pageSize); examListPaged.total_count = theList.Count; examListPaged.total_pages = pList.TotalPages; examListPaged.page_index = pList.PageIndex; examListPaged.next = pList.HasNextPage; examListPaged.previous = pList.HasPreviousPage; examListPaged.exams = pList; } returnResponse = Ok(ReturnResponse.GetSuccessStatus(examListPaged)); } else if (theList is int && theList == (int)Message.NotAllowedToResource) { responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.NotAllowedToResource, responseMessage)); } else if(theList == null) { responseMessage = _repository.GetMessageByCode(Message.NoData.ToString()); returnResponse = Ok(ReturnResponse.GetFailureStatus((int)Message.NoData, responseMessage)); } else { responseMessage = _repository.GetMessageByCode(Message.Failure.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.Failure, responseMessage)); } return returnResponse; } /// /// This endpoint will return the details of the exam. /// Error Conditions: Invalid Exam, Attempt limit Over, Unknown error /// /// /// /// Invalid input /// Resource is not allowed /// Unknown error [HttpGet("{language}/ExamAttempts/{exam_id}")] [ProducesResponseType(typeof(ExamDetailViewModel), 200)] [Authorize(Roles = "Student")] public IActionResult GetExamDetails(string language, int exam_id) { IActionResult returnResponse = null; int user_id = Security.GetIdFromJwtToken(UserClaim.UserId, HttpContext.User.Identity as ClaimsIdentity); int language_id = _repository.GetLanguageIdByCode(language); if (language_id <= 0) { responseMessage = _repository.GetMessageByCode(Message.InvalidInput.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.InvalidInput, responseMessage)); return returnResponse; } bool isValidExam = _repository.isValidExam(institute_id, exam_id, user_id); if (isValidExam == false) { responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.NotAllowedToResource, responseMessage)); return returnResponse; } // Get exam details ExamDetailViewModel dynamic attempt = _repository.GetExamDetails(base.InstituteId, user_id, exam_id); if (attempt != null && attempt is ExamDetailViewModel) { returnResponse = Ok(ReturnResponse.GetSuccessStatus(attempt)); } else if(attempt is int && attempt == (int)Message.NotAllowedToResource) { responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString(), Constant.ExamAttempt); returnResponse = BadRequest(ReturnResponse.GetFailureStatus(responseMessage)); } else { responseMessage = _repository.GetMessageByCode(Message.Failure.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.Failure, responseMessage)); } return returnResponse; } /// /// This endpoint will create a new attempt for the exam. /// Error Conditions: Invalid Exam, Attempt limit Over, Unknown error /// /// /// /// Invalid input /// Resource is not allowed /// Unknown error [HttpPost("{language}/ExamAttempts/{exam_id}")] [ProducesResponseType(typeof(ExamAttemptAllQuestionsViewModel), 200)] [Authorize(Roles = "Student")] public IActionResult AddNewExamAttempt(string language, int exam_id) { //Step1: Get Institute & User details IActionResult returnResponse = null; int user_id = Security.GetIdFromJwtToken(UserClaim.UserId, HttpContext.User.Identity as ClaimsIdentity); int language_id = _repository.GetLanguageIdByCode(language); if (language_id <= 0) return null; bool isValidExam = _repository.isValidExam(institute_id, exam_id, user_id); if (isValidExam == false) { responseMessage = _repository.GetMessageByCode(Message.InvalidInput.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.NotAllowedToResource, responseMessage)); return returnResponse; } //IsCreditavailable : check if valid subscription is there and if this exam is not yet attempted during subscription period then deduct credits from subcription do below operation //better to add subscription id for each attempt you make // Create an attempt dynamic attempt = _repository.AddNewAttemptOfTheExam(base.InstituteId, user_id, exam_id); if (attempt is int && attempt == (int)Message.InvalidInput) { responseMessage = _repository.GetMessageByCode(Message.InvalidInput.ToString(), Constant.Exam); return BadRequest(ReturnResponse.GetFailureStatus(responseMessage)); } else if (attempt is int && attempt == (int)Message.NotAllowedToResource) { responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString(), Constant.Exam); return BadRequest(ReturnResponse.GetFailureStatus(responseMessage)); } else if(attempt is int && attempt == (int)Message.Failure) { responseMessage = _repository.GetMessageByCode(Message.Failure.ToString()); return BadRequest(ReturnResponse.GetFailureStatus((int)Message.Failure, responseMessage)); } dynamic questions = _repository.GetExamAttemptQuestions(language_id, user_id, attempt); if (questions is ExamAttemptAllQuestionsViewModel) { returnResponse = Ok(ReturnResponse.GetSuccessStatus(questions)); } else { responseMessage = _repository.GetMessageByCode(Message.Failure.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.Failure, responseMessage)); } return returnResponse; } /// /// Attach Bookmark To Exams /// /// /// Invalid input /// Resource is not allowed /// Unknown error [HttpPost("Batches/{batch_id}/ExamAttempts/{exam_id}/Bookmark")] [ProducesResponseType(typeof(int), 200)] [Authorize(Roles = "Student")] public IActionResult AttachBookmarkToExams(int batch_id, int exam_id, [FromBody] ExamBookMarkStatus bookMarkStatus) { IActionResult returnResponse = null; string return_message = string.Empty; int user_id = Security.GetIdFromJwtToken(UserClaim.UserId, HttpContext.User.Identity as ClaimsIdentity); if (bookMarkStatus == null) { responseMessage = _repository.GetMessageByCode(Message.InvalidInput.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.InvalidInput, responseMessage)); } int recordsEffected = 0; if (bookMarkStatus.isBookmark == true) recordsEffected = _repository.AttachBookmarkToExams(base.InstituteId, batch_id, user_id, exam_id); else recordsEffected = _repository.DetachBookmarkFromExams(user_id, exam_id); if(recordsEffected > 0) { returnResponse = Ok(ReturnResponse.GetSuccessStatus(return_message)); } else if (recordsEffected == (int)Message.NotAllowedToResource) { responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.NotAllowedToResource, responseMessage)); } else { responseMessage = _repository.GetMessageByCode(Message.Failure.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.Failure, responseMessage)); } return returnResponse; } /// /// This endpoint retrieves all attempts for the authenticated user. /// /// /// /// /// No Data /// Unknown error [HttpGet("{language}/ExamAttempts")] [ProducesResponseType(typeof(List), 200)] [Authorize(Roles = "Student")] public IActionResult GetAllExamAttempts([FromQuery] bool? isActive, [FromQuery] string sortBy, string sortOrder) { //Step1: Get Institute & User details IActionResult returnResponse = null; institute_id = base.InstituteId; int user_id = int.Parse(Security.GetValueFromToken("UserId", HttpContext.User.Identity as ClaimsIdentity)); // Create an attaempt List attempts; if (sortBy == null) sortBy = "DATE"; if (sortOrder == null) sortOrder = "D"; attempts = _repository.GetAllExamAttempts(user_id, isActive, sortBy, sortOrder); if (attempts == null || attempts.Count == 0) { responseMessage = _repository.GetMessageByCode(Message.NoData.ToString()); returnResponse = Ok(ReturnResponse.GetFailureStatus((int)Message.NoData, responseMessage)); } else { returnResponse = Ok(ReturnResponse.GetSuccessStatus(attempts)); } return returnResponse; } /// /// This endpoint ends an attempt and return the status as Completed and cannot be started again /// /// /// Invalid input /// Unknown error [HttpPut("{language}/ExamAttempts/{exam_attempt_id}/End")] [ProducesResponseType(typeof(int), 200)] [Authorize(Roles = "Student")] public IActionResult EndExamAttempt(int exam_attempt_id) { //Step1: Get Institute & User details IActionResult returnResponse = null; institute_id = base.InstituteId; int user_id = Security.GetIdFromJwtToken(UserClaim.UserId, HttpContext.User.Identity as ClaimsIdentity); // Create an attaempt int endAttempt = _repository.EndExamAttempt(user_id, exam_attempt_id); if(endAttempt > 0) { returnResponse = Ok(ReturnResponse.GetSuccessStatus(endAttempt)); } else if (endAttempt == (int)Message.InvalidInput) { responseMessage = _repository.GetMessageByCode(Message.InvalidInput.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.InvalidInput, responseMessage)); } else { responseMessage = _repository.GetMessageByCode(Message.Failure.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.Failure, responseMessage)); } return returnResponse; } /// /// This endpoint starts a paused attempt. This is for restarting the timer calculation incase of a paused attempt. /// /// /// Invalid input /// Resource is not allowed /// Unknown error [HttpPut("{language}/ExamAttempts/{attempt_id}/Pause")] [ProducesResponseType(typeof(DurationView), 200)] [Authorize(Roles = "Student")] public IActionResult PauseExamAttempt(int attempt_id) { //Step1: Get Institute & User details IActionResult returnResponse = null; institute_id = base.InstituteId; int user_id = Security.GetIdFromJwtToken(UserClaim.UserId, HttpContext.User.Identity as ClaimsIdentity); // Start an attempt dynamic time = _repository.PauseExamAttempt(user_id, attempt_id); if(time is DurationView && time.time_left > 0) { returnResponse = Ok(ReturnResponse.GetSuccessStatus(time)); } else if (time is int && time == (int)Message.NotAllowedToResource) { responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.NotAllowedToResource, responseMessage)); } else if (time is int && time == (int)Message.InvalidInput) { responseMessage = _repository.GetMessageByCode(Message.InvalidInput.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.InvalidInput, responseMessage)); } else { responseMessage = _repository.GetMessageByCode(Message.Failure.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.Failure, responseMessage)); } return returnResponse; } /// /// This endpoint returns all questions for an attempt. /// /// /// /// Invalid input /// No data /// Unknown error [HttpGet("{language}/ExamAttempts/{attempt_id}/Questions")] [ProducesResponseType(typeof(ExamAttemptAllQuestionsViewModel), 200)] [Authorize(Roles = "Student")] public IActionResult GetExamAttemptQuestions(string language, int attempt_id) { //Step1: Get Institute & User details IActionResult returnResponse = null; institute_id = base.InstituteId; int user_id = int.Parse(Security.GetValueFromToken("UserId", HttpContext.User.Identity as ClaimsIdentity)); int language_id = _repository.GetLanguageIdByCode(language); if (language_id <= 0) { responseMessage = _repository.GetMessageByCode(Message.InvalidInput.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.InvalidInput, responseMessage)); return returnResponse; } // Get attempt qns dynamic questions = _repository.GetExamAttemptQuestions(language_id, user_id, attempt_id); if (questions is ExamAttemptAllQuestionsViewModel) { returnResponse = Ok(ReturnResponse.GetSuccessStatus(questions)); } else if (questions is int && questions == (int)Message.InvalidInput) { responseMessage = _repository.GetMessageByCode(Message.InvalidInput.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.InvalidInput, responseMessage)); } else if (questions is int && questions == (int)Message.NoData) { responseMessage = _repository.GetMessageByCode(Message.NoData.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus(responseMessage)); } else { responseMessage = _repository.GetMessageByCode(Message.Failure.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.Failure, responseMessage)); } return returnResponse; } /// /// This endpoint returns all questions for an attempt. /// /// /// Resource is not allowed /// Unknown error [HttpPut("ExamAttempts/{attempt_id}/HeartBeat")] [ProducesResponseType(typeof(DurationView), 200)] [Authorize(Roles = "Student")] //attempt is in start state & enddate is gt now, user is the valid attemp owner, check valid option ids? then update public IActionResult HeartBeat(int attempt_id) { //Step1: Get Institute & User details IActionResult returnResponse = null; institute_id = base.InstituteId; int user_id = Security.GetIdFromJwtToken(UserClaim.UserId, HttpContext.User.Identity as ClaimsIdentity); // Update answers DurationView time = _repository.HeartBeat(attempt_id, user_id); //TBD: if teacher get teacher classes and check if the exam class belongs to teacher classes if (time == null) { responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString()); returnResponse = Unauthorized(ReturnResponse.GetFailureStatus(responseMessage)); return returnResponse; } else { returnResponse = Ok(ReturnResponse.GetSuccessStatus(time)); } return returnResponse; } /// /// This endpoint will update the answer of the attempted question. /// /// /// /// Invalid input /// Resource is not allowed /// Unknown error [HttpPut("ExamAttempts/{attempt_id}/UpdateAnswer")] [ProducesResponseType(typeof(DurationView), 200)] [Authorize(Roles = "Student")] //attempt is in start state & enddate is gt now, user is the valid attemp owner, check valid option ids? then update public IActionResult UpdateAnswer(int attempt_id, [FromBody] QuestionAnswerViewModel responses) { //Step1: Get Institute & User details IActionResult returnResponse = null; institute_id = base.InstituteId; int user_id = Security.GetIdFromJwtToken(UserClaim.UserId, HttpContext.User.Identity as ClaimsIdentity); // Update answers dynamic time = _repository.UpdateAnswer(attempt_id, user_id, responses); //TBD: if teacher get teacher classes and check if the exam class belongs to teacher classes if(time is DurationView) { returnResponse = Ok(ReturnResponse.GetSuccessStatus(time)); } if (time is int && time == (int)Message.NotAllowedToResource) { responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.NotAllowedToResource, responseMessage)); } else if(time is int && time == (int)Message.InvalidInput) { responseMessage = _repository.GetMessageByCode(Message.InvalidInput.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.InvalidInput, responseMessage)); } else { responseMessage = _repository.GetMessageByCode(Message.Failure.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.Failure, responseMessage)); } return returnResponse; } /// /// View detailed report of a user completed attempt. /// /// /// /// Invalid input /// Resource is not allowed /// Unknown error [HttpGet("{language}/ExamAttempts/{exam_attempt_id}/Report")] [ProducesResponseType(typeof(ExamAttemptReportViewModel), 200)] [Authorize(Roles = "Student")] public IActionResult Report(string language, int exam_attempt_id) { //Step1: Get Institute & User details IActionResult returnResponse = null; int user_id = Security.GetIdFromJwtToken(UserClaim.UserId, HttpContext.User.Identity as ClaimsIdentity); int language_id = _repository.GetLanguageIdByCode(language); if (language_id <= 0) return null; // Get an attaempt dynamic report = _repository.ViewReportOfTheExam(base.InstituteId, language_id, user_id, exam_attempt_id); //TBD: if teacher get teacher classes and check if the exam class belongs to teacher classes if(report is ExamAttemptReportViewModel) { returnResponse = Ok(ReturnResponse.GetSuccessStatus(report)); } else if (report is int && report == (int)Message.NotAllowedToResource) { responseMessage = _repository.GetMessageByCode(Message.NotAllowedToResource.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.NotAllowedToResource, responseMessage)); } else if(report is int && report == (int)Message.InvalidInput) { responseMessage = _repository.GetMessageByCode(Message.InvalidInput.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.InvalidInput, responseMessage)); } else { responseMessage = _repository.GetMessageByCode(Message.Failure.ToString()); returnResponse = BadRequest(ReturnResponse.GetFailureStatus((int)Message.Failure, responseMessage)); } return returnResponse; } #endregion } }