2024-12-02 13:24:34 +00:00
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 < ExamAttempts , EFCoreExamAttemptRepository >
{
EFCoreExamAttemptRepository _repository ;
string responseMessage = string . Empty ;
int institute_id ;
public ExamAttemptsController ( EFCoreExamAttemptRepository repository ) : base ( repository )
{
_repository = repository ;
}
#region ExamAttempts
/// <summary>
/// Get all exams
/// </summary>
/// <param name="language"></param>
/// <param name="batch_id"></param>
/// <param name="subject_id"></param>
/// <param name="sortBy"></param>
/// <param name="sortOrder"></param>
/// <param name="pageNumber"></param>
/// <param name="pageSize"></param>
/// <response code="-4000">Invalid input</response>
/// <response code="-4010">Resource is not allowed</response>
/// <response code="-4040">No Data</response>
/// <response code="-1">Unknown error</response>
[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 < ExamAttemptAllExamModel > & & theList ! = null )
{
if ( pageNumber ! = null & & pageSize ! = null )
{
PaginatedList < ExamAttemptAllExamModel > pList = PaginatedList < ExamAttemptAllExamModel > . 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 ;
}
/// <summary>
/// Get all live exams
/// </summary>
/// <param name="language"></param>
/// <param name="batch_id"></param>
/// <param name="subject_id"></param>
/// <param name="sortBy"></param>
/// <param name="sortOrder"></param>
/// <response code="-4000">Invalid input</response>
/// <response code="-4010">Resource is not allowed</response>
/// <response code="-4040">No Data</response>
/// <response code="-1">Unknown error</response>
[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 < ExamAttemptAllExamModel > & & theList ! = null )
{
if ( pageNumber ! = null & & pageSize ! = null )
{
PaginatedList < ExamAttemptAllExamModel > pList = PaginatedList < ExamAttemptAllExamModel > . 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 ;
}
/// <summary>
/// Get all live exams by author (subject id = 0 means fullexam, -1 means all exam, other than that will return based on subject)
/// </summary>
/// <param name="language"></param>
/// <param name="batch_id"></param>
/// <param name="author_id"></param>
/// <param name="subject_id"></param>
/// <param name="sortBy"></param>
/// <param name="sortOrder"></param>
/// <response code="-4000">Invalid input</response>
/// <response code="-4010">Resource is not allowed</response>
/// <response code="-4040">No Data</response>
/// <response code="-1">Unknown error</response>
[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 < ExamAttemptAllExamModel > & & theList ! = null )
{
if ( pageNumber ! = null & & pageSize ! = null )
{
PaginatedList < ExamAttemptAllExamModel > pList = PaginatedList < ExamAttemptAllExamModel > . 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 ;
}
/// <summary>
/// Get all attempted exams
/// </summary>
/// <param name="language"></param>
/// <param name="sortBy"></param>
/// <param name="sortOrder"></param>
/// <response code="-4000">Invalid input</response>
/// <response code="-4010">Resource is not allowed</response>
/// <response code="-4040">No Data</response>
/// <response code="-1">Unknown error</response>
[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 < ExamAttemptAttemptedExamModel > )
{
if ( pageNumber ! = null & & pageSize ! = null )
{
PaginatedList < ExamAttemptAttemptedExamModel > pList = PaginatedList < ExamAttemptAttemptedExamModel > . 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 ;
}
/// <summary>
/// This endpoint will return the details of the exam.
/// Error Conditions: Invalid Exam, Attempt limit Over, Unknown error
/// </summary>
/// <param name="exam_id"></param>
/// <param name="language"></param>
/// <response code="-4000">Invalid input</response>
/// <response code="-4010">Resource is not allowed</response>
/// <response code="-1">Unknown error</response>
[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 ;
}
/// <summary>
/// This endpoint will create a new attempt for the exam.
/// Error Conditions: Invalid Exam, Attempt limit Over, Unknown error
/// </summary>
/// <param name="exam_id"></param>
/// <param name="language"></param>
/// <response code="-4000">Invalid input</response>
/// <response code="-4010">Resource is not allowed</response>
/// <response code="-1">Unknown error</response>
[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 ;
}
/// <summary>
/// Attach Bookmark To Exams
/// </summary>
/// <param name="bookMarkStatus"></param>
/// <response code="-4000">Invalid input</response>
/// <response code="-4010">Resource is not allowed</response>
/// <response code="-1">Unknown error</response>
[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 ;
}
/// <summary>
/// This endpoint retrieves all attempts for the authenticated user.
/// </summary>
/// <param name="isActive"></param>
/// <param name="sortBy"></param>
/// <param name="sortOrder"></param>
/// <response code="-4040">No Data</response>
/// <response code="-1">Unknown error</response>
[HttpGet("{language}/ExamAttempts")]
[ProducesResponseType(typeof(List<ExamAttemptViewModel>), 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 < ExamAttemptViewModel > 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 ;
}
/// <summary>
/// This endpoint ends an attempt and return the status as Completed and cannot be started again
/// </summary>
/// <param name="exam_attempt_id"></param>
/// <response code="-4000">Invalid input</response>
/// <response code="-1">Unknown error</response>
2025-10-29 17:18:58 +00:00
[HttpPost("{language}/ExamAttempts/{exam_attempt_id}/End")]
2024-12-02 13:24:34 +00:00
[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 ;
}
/// <summary>
/// This endpoint starts a paused attempt. This is for restarting the timer calculation incase of a paused attempt.
/// </summary>
/// <param name="attempt_id"></param>
/// <response code="-4000">Invalid input</response>
/// <response code="-4010">Resource is not allowed</response>
/// <response code="-1">Unknown error</response>
2025-10-29 17:18:58 +00:00
[HttpPost("{language}/ExamAttempts/{attempt_id}/Pause")]
2024-12-02 13:24:34 +00:00
[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 ;
}
/// <summary>
/// This endpoint returns all questions for an attempt.
/// </summary>
/// <param name="language"></param>
/// <param name="attempt_id"></param>
/// <response code="-4000">Invalid input</response>
/// <response code="-4040">No data</response>
/// <response code="-1">Unknown error</response>
[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 ;
}
/// <summary>
/// This endpoint returns all questions for an attempt.
/// </summary>
/// <param name="attempt_id"></param>
/// <response code="-4010">Resource is not allowed</response>
/// <response code="-1">Unknown error</response>
2025-10-29 17:18:58 +00:00
[HttpPost("ExamAttempts/{attempt_id}/HeartBeat")]
2024-12-02 13:24:34 +00:00
[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 ;
}
/// <summary>
/// This endpoint will update the answer of the attempted question.
/// </summary>
/// <param name="attempt_id"></param>
/// <param name="responses"></param>
/// <response code="-4000">Invalid input</response>
/// <response code="-4010">Resource is not allowed</response>
/// <response code="-1">Unknown error</response>
2025-10-29 17:18:58 +00:00
[HttpPost("ExamAttempts/{attempt_id}/UpdateAnswer")]
2024-12-02 13:24:34 +00:00
[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 ;
}
/// <summary>
/// View detailed report of a user completed attempt.
/// </summary>
/// <param name="language"></param>
/// <param name="exam_attempt_id"></param>
/// <response code="-4000">Invalid input</response>
/// <response code="-4010">Resource is not allowed</response>
/// <response code="-1">Unknown error</response>
[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
}
}