825 lines
39 KiB
C#
825 lines
39 KiB
C#
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>
|
|
[HttpPost("{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;
|
|
}
|
|
|
|
/// <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>
|
|
[HttpPost("{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;
|
|
}
|
|
|
|
/// <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>
|
|
[HttpPost("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;
|
|
}
|
|
|
|
|
|
/// <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>
|
|
[HttpPost("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;
|
|
}
|
|
|
|
/// <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
|
|
|
|
|
|
}
|
|
}
|