#15 the first phase of approval / rejection api

This commit is contained in:
Hamid Reza Mohammadi 2020-10-07 21:18:07 +03:30
parent 2d075c6ac2
commit d38eae4f83
5 changed files with 162 additions and 22 deletions

View File

@ -69,10 +69,14 @@ namespace RMuseum.Controllers
} }
/// <summary> /// <summary>
/// updates narration metadata, user must have narration::moderate permission to change narration status from pending to approved or rejected or modify other users narrations metadata /// updates narration metadata
/// </summary> /// </summary>
/// <param name="id"></param> /// <param name="id"></param>
/// <param name="metadata"></param> /// <param name="metadata"></param>
/// <remarks>
/// reviewstatus cannot be set to Approved or Rejected using this method, use moderate method instead
/// TODO: for approved narrations provide another API or solution
/// </remarks>
/// <returns></returns> /// <returns></returns>
[HttpPut("{id}")] [HttpPut("{id}")]
@ -86,25 +90,21 @@ namespace RMuseum.Controllers
var narration = await _audioService.Get(id); var narration = await _audioService.Get(id);
if (!string.IsNullOrEmpty(narration.ExceptionString)) if (!string.IsNullOrEmpty(narration.ExceptionString))
return BadRequest(narration.ExceptionString);
if(narration.Result.Owner.Id != id || metadata.ReviewStatus == AudioReviewStatus.Approved || metadata.ReviewStatus == AudioReviewStatus.Rejected)
{ {
Guid sessionId = new Guid(User.Claims.FirstOrDefault(c => c.Type == "SessionId").Value); return BadRequest(narration.ExceptionString);
RServiceResult<bool> }
canModerate =
await _userPermissionChecker.Check
(
loggedOnUserId,
sessionId,
RMuseumSecurableItem.AudioNarrationEntityShortName,
RMuseumSecurableItem.ModerateOperationShortName
);
if (!string.IsNullOrEmpty(canModerate.ExceptionString))
return BadRequest(canModerate.ExceptionString);
if (!canModerate.Result) if (!string.IsNullOrEmpty(narration.ExceptionString))
return StatusCode((int)HttpStatusCode.Forbidden); {
return BadRequest(narration.ExceptionString);
}
if (narration.Result == null)
return NotFound();
if (metadata.ReviewStatus == AudioReviewStatus.Approved || metadata.ReviewStatus == AudioReviewStatus.Rejected)
{
return StatusCode((int)HttpStatusCode.Forbidden);
} }
var res = await _audioService.UpdatePoemNarration(id, metadata); var res = await _audioService.UpdatePoemNarration(id, metadata);
@ -114,6 +114,37 @@ namespace RMuseum.Controllers
return Ok(res.Result); return Ok(res.Result);
} }
/// <summary>
/// Moderate pending narration
/// </summary>
/// <param name="id"></param>
/// <param name="model"></param>
/// <returns></returns>
[HttpPut("moderate/{id}")]
[Authorize(Policy = RMuseumSecurableItem.AudioNarrationEntityShortName + ":" + RMuseumSecurableItem.ModerateOperationShortName)]
[ProducesResponseType((int)HttpStatusCode.OK, Type = typeof(PoemNarrationUpdateViewModel))]
[ProducesResponseType((int)HttpStatusCode.BadRequest, Type = typeof(string))]
[ProducesResponseType((int)HttpStatusCode.Forbidden, Type = typeof(string))]
public async Task<IActionResult> ModeratePoemNarration(Guid id, [FromBody] PoemNarrationModerateViewModel model)
{
Guid loggedOnUserId = new Guid(User.Claims.FirstOrDefault(c => c.Type == "UserId").Value);
var narration = await _audioService.Get(id);
if (!string.IsNullOrEmpty(narration.ExceptionString))
{
return BadRequest(narration.ExceptionString);
}
if (narration.Result == null)
return NotFound();
var res = await _audioService.ModeratePoemNarration(id, loggedOnUserId, model);
if (!string.IsNullOrEmpty(res.ExceptionString))
return BadRequest(res.ExceptionString);
return Ok(res.Result);
}
/// <summary> /// <summary>

View File

@ -0,0 +1,18 @@
namespace RMuseum.Models.GanjoorAudio.ViewModels
{
/// <summary>
/// Poem Narration Moderation View Model
/// </summary>
public class PoemNarrationModerateViewModel
{
/// <summary>
/// Approve or Reject
/// </summary>
public bool Approve { get; set; }
/// <summary>
/// Rejection Message
/// </summary>
public string Message { get; set; }
}
}

View File

@ -631,10 +631,22 @@
</member> </member>
<member name="M:RMuseum.Controllers.AudioNarrationController.UpdatePoemNarration(System.Guid,RMuseum.Models.GanjoorAudio.ViewModels.PoemNarrationUpdateViewModel)"> <member name="M:RMuseum.Controllers.AudioNarrationController.UpdatePoemNarration(System.Guid,RMuseum.Models.GanjoorAudio.ViewModels.PoemNarrationUpdateViewModel)">
<summary> <summary>
updates narration metadata, user must have narration::moderate permission to change narration status from pending to approved or rejected or modify other users narrations metadata updates narration metadata
</summary> </summary>
<param name="id"></param> <param name="id"></param>
<param name="metadata"></param> <param name="metadata"></param>
<remarks>
reviewstatus cannot be set to Approved or Rejected using this method, use moderate method instead
TODO: for approved narrations provide another API or solution
</remarks>
<returns></returns>
</member>
<member name="M:RMuseum.Controllers.AudioNarrationController.ModeratePoemNarration(System.Guid,RMuseum.Models.GanjoorAudio.ViewModels.PoemNarrationModerateViewModel)">
<summary>
Moderate pending narration
</summary>
<param name="id"></param>
<param name="model"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:RMuseum.Controllers.AudioNarrationController.GetUploads(RSecurityBackend.Models.Generic.PagingParameterModel,System.Boolean)"> <member name="M:RMuseum.Controllers.AudioNarrationController.GetUploads(RSecurityBackend.Models.Generic.PagingParameterModel,System.Boolean)">
@ -1898,6 +1910,21 @@
is default is default
</summary> </summary>
</member> </member>
<member name="T:RMuseum.Models.GanjoorAudio.ViewModels.PoemNarrationModerateViewModel">
<summary>
Poem Narration Moderation View Model
</summary>
</member>
<member name="P:RMuseum.Models.GanjoorAudio.ViewModels.PoemNarrationModerateViewModel.Approve">
<summary>
Approve or Reject
</summary>
</member>
<member name="P:RMuseum.Models.GanjoorAudio.ViewModels.PoemNarrationModerateViewModel.Message">
<summary>
Rejection Message
</summary>
</member>
<member name="T:RMuseum.Models.GanjoorAudio.ViewModels.PoemNarrationUpdateViewModel"> <member name="T:RMuseum.Models.GanjoorAudio.ViewModels.PoemNarrationUpdateViewModel">
<summary> <summary>
Poem Narration View Model for updates Poem Narration View Model for updates
@ -3653,6 +3680,15 @@
<param name="files"></param> <param name="files"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:RMuseum.Services.IAudioNarrationService.ModeratePoemNarration(System.Guid,System.Guid,RMuseum.Models.GanjoorAudio.ViewModels.PoemNarrationModerateViewModel)">
<summary>
Moderate pending narration
</summary>
<param name="id"></param>
<param name="moderatorId"></param>
<param name="model"></param>
<returns></returns>
</member>
<member name="M:RMuseum.Services.IAudioNarrationService.GetUploadSession(System.Guid)"> <member name="M:RMuseum.Services.IAudioNarrationService.GetUploadSession(System.Guid)">
<summary> <summary>
Get Upload Session (including files) Get Upload Session (including files)
@ -4462,6 +4498,15 @@
<param name="files"></param> <param name="files"></param>
<returns></returns> <returns></returns>
</member> </member>
<member name="M:RMuseum.Services.Implementation.AudioNarrationService.ModeratePoemNarration(System.Guid,System.Guid,RMuseum.Models.GanjoorAudio.ViewModels.PoemNarrationModerateViewModel)">
<summary>
Moderate pending narration
</summary>
<param name="id"></param>
<param name="moderatorId"></param>
<param name="model"></param>
<returns></returns>
</member>
<member name="M:RMuseum.Services.Implementation.AudioNarrationService.GetUploadSession(System.Guid)"> <member name="M:RMuseum.Services.Implementation.AudioNarrationService.GetUploadSession(System.Guid)">
<summary> <summary>
Get Upload Session (including files) Get Upload Session (including files)

View File

@ -66,6 +66,15 @@ namespace RMuseum.Services
/// <returns></returns> /// <returns></returns>
Task<RServiceResult<UploadSession>> FinalizeNewUploadSession(UploadSession session, UploadSessionFile[] files); Task<RServiceResult<UploadSession>> FinalizeNewUploadSession(UploadSession session, UploadSessionFile[] files);
/// <summary>
/// Moderate pending narration
/// </summary>
/// <param name="id"></param>
/// <param name="moderatorId"></param>
/// <param name="model"></param>
/// <returns></returns>
Task<RServiceResult<bool>> ModeratePoemNarration(Guid id, Guid moderatorId, PoemNarrationModerateViewModel model);
/// <summary> /// <summary>
/// Get Upload Session (including files) /// Get Upload Session (including files)
/// </summary> /// </summary>

View File

@ -74,7 +74,12 @@ namespace RMuseum.Services.Implementation
{ {
try try
{ {
return new RServiceResult<PoemNarrationViewModel>(new PoemNarrationViewModel(await _context.AudioFiles.Where(a => a.Id == id).SingleOrDefaultAsync())); var narration = await _context.AudioFiles.Where(a => a.Id == id).SingleOrDefaultAsync();
if(narration == null)
{
return new RServiceResult<PoemNarrationViewModel>(null);
}
return new RServiceResult<PoemNarrationViewModel>(new PoemNarrationViewModel(narration));
} }
catch (Exception exp) catch (Exception exp)
{ {
@ -111,6 +116,7 @@ namespace RMuseum.Services.Implementation
} }
} }
/// <summary> /// <summary>
/// imports data from ganjoor MySql database /// imports data from ganjoor MySql database
/// </summary> /// </summary>
@ -494,9 +500,40 @@ namespace RMuseum.Services.Implementation
} }
} }
/// <summary>
/// Moderate pending narration
/// </summary>
/// <param name="id"></param>
/// <param name="moderatorId"></param>
/// <param name="model"></param>
/// <returns></returns>
public async Task<RServiceResult<bool>> ModeratePoemNarration(Guid id, Guid moderatorId, PoemNarrationModerateViewModel model)
{
try
{
PoemNarration narration = await _context.AudioFiles.Where(a => a.Id == id).SingleOrDefaultAsync();
if (narration == null)
return new RServiceResult<bool>(false, "404");
if (narration.ReviewStatus != AudioReviewStatus.Pending)
return new RServiceResult<bool>(false, "خوانش می‌بایست در وضعیت در انتظار بازبینی باشد.");
narration.ReviewDate = DateTime.Now;
narration.ReviewerId = moderatorId;
narration.ReviewStatus = model.Approve ? AudioReviewStatus.Approved : AudioReviewStatus.Rejected;
narration.ReviewMsg = model.Message;
_context.AudioFiles.Update(narration);
await _context.SaveChangesAsync();
//TODO: 1 . notify user on moderation result
//TODO: 2 . start a background job for finalizing approved narrations
//TODO: 3 . notify user on publication of approved narration
return new RServiceResult<bool>(true);
}
catch (Exception exp)
{
return new RServiceResult<bool>(false, exp.ToString());
}
}
/// <summary> /// <summary>