Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Psp 6953 disposition checklist and generic checklist components. #3694

Merged
merged 2 commits into from
Jan 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Pims.Api.Models.Concepts.AcquisitionFile;
using Pims.Api.Models.Models.Concepts.File;
using Pims.Api.Policies;
using Pims.Api.Services;
using Pims.Dal.Security;
Expand Down Expand Up @@ -50,12 +51,12 @@ public ChecklistController(IAcquisitionFileService acquisitionService, IMapper m
[HttpGet("{id:long}/checklist")]
[HasPermission(Permissions.AcquisitionFileView)]
[Produces("application/json")]
[ProducesResponseType(typeof(IEnumerable<AcquisitionFileChecklistItemModel>), 200)]
[ProducesResponseType(typeof(IEnumerable<FileChecklistItemModel>), 200)]
[SwaggerOperation(Tags = new[] { "acquisitionfile" })]
public IActionResult GetAcquisitionFileChecklist([FromRoute] long id)
{
var checklist = _acquisitionService.GetChecklistItems(id);
return new JsonResult(_mapper.Map<IEnumerable<AcquisitionFileChecklistItemModel>>(checklist));
return new JsonResult(_mapper.Map<IEnumerable<FileChecklistItemModel>>(checklist));
}

/// <summary>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
using System.Collections.Generic;
using MapsterMapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Pims.Api.Models.Concepts.DispositionFile;
using Pims.Api.Models.Models.Concepts.File;
using Pims.Api.Policies;
using Pims.Api.Services;
using Pims.Dal.Security;
using Swashbuckle.AspNetCore.Annotations;

namespace Pims.Api.Areas.Disposition.Controllers
{
/// <summary>
/// ChecklistController class, provides endpoints for interacting with disposition files checklists.
/// </summary>
[Authorize]
[ApiController]
[ApiVersion("1.0")]
[Area("dispositionfiles")]
[Route("v{version:apiVersion}/[area]")]
[Route("[area]")]
public class ChecklistController : ControllerBase
{
#region Variables
private readonly IDispositionFileService _dispositionService;
private readonly IMapper _mapper;
#endregion

#region Constructors

/// <summary>
/// Creates a new instance of a ChecklistController class, initializes it with the specified arguments.
/// </summary>
/// <param name="dispositionService"></param>
/// <param name="mapper"></param>
///
public ChecklistController(IDispositionFileService dispositionService, IMapper mapper)
{
_dispositionService = dispositionService;
_mapper = mapper;
}
#endregion

#region Endpoints

/// <summary>
/// Get the disposition file checklist.
/// </summary>
/// <returns>The checklist items.</returns>
[HttpGet("{id:long}/checklist")]
[HasPermission(Permissions.DispositionView)]
[Produces("application/json")]
[ProducesResponseType(typeof(IEnumerable<FileChecklistItemModel>), 200)]
[SwaggerOperation(Tags = new[] { "dispositionfile" })]
public IActionResult GetDispositionFileChecklist([FromRoute] long id)
{
var checklist = _dispositionService.GetChecklistItems(id);
return new JsonResult(_mapper.Map<IEnumerable<FileChecklistItemModel>>(checklist));
}

/// <summary>
/// Update the disposition file checklist.
/// </summary>
/// <returns>The updated checklist items.</returns>
[HttpPut("{id:long}/checklist")]
[HasPermission(Permissions.DispositionEdit)]
[Produces("application/json")]
[ProducesResponseType(typeof(DispositionFileModel), 200)]
[SwaggerOperation(Tags = new[] { "dispositionfile" })]
public IActionResult UpdateDispositionFileChecklist([FromBody] DispositionFileModel dispositionFileModel)
{
var dispositionFileEntity = _mapper.Map<Dal.Entities.PimsDispositionFile>(dispositionFileModel);
var dispositionFile = _dispositionService.UpdateChecklistItems(dispositionFileEntity);
return new JsonResult(_mapper.Map<DispositionFileModel>(dispositionFile));
}

#endregion
}
}
6 changes: 6 additions & 0 deletions source/backend/api/Controllers/LookupController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,9 @@ public IActionResult GetAll()
var dispositionInitiatingDocTypes = _mapper.Map<Model.LookupModel[]>(_lookupRepository.GetAllDispositionInitiatingDocTypes());
var dispositionTypes = _mapper.Map<Model.LookupModel[]>(_lookupRepository.GetAllDispositionTypes());
var dispositionOfferStatusTypes = _mapper.Map<Model.LookupModel[]>(_lookupRepository.GetAllDispositionOfferStatusTypes());
var dispositionChecklistItemStatusTypes = _mapper.Map<Model.LookupModel[]>(_lookupRepository.GetAllDispositionChecklistItemStatusTypes());
var dispositionChecklistItemTypes = _mapper.Map<Model.LookupModel[]>(_lookupRepository.GetAllDispositionChecklistItemTypes());
var dispositionChecklistSectionTypes = _mapper.Map<Model.LookupModel[]>(_lookupRepository.GetAllDispositionChecklistSectionTypes());

var codes = new List<object>();
codes.AddRange(areaUnitTypes);
Expand Down Expand Up @@ -214,6 +217,9 @@ public IActionResult GetAll()
codes.AddRange(dispositionTypes);
codes.AddRange(dispositionStatusTypes);
codes.AddRange(dispositionOfferStatusTypes);
codes.AddRange(dispositionChecklistItemStatusTypes);
codes.AddRange(dispositionChecklistItemTypes);
codes.AddRange(dispositionChecklistSectionTypes);

var response = new JsonResult(codes);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Linq;
using System.Security.Claims;
using Pims.Dal.Entities.Models;
using Pims.Dal.Exceptions;
using Pims.Dal.Repositories;

Expand Down
2 changes: 1 addition & 1 deletion source/backend/api/Services/AcquisitionFileService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -792,7 +792,7 @@ private void PopulateAcquisitionChecklist(PimsAcquisitionFile acquisitionFile)
private void AppendToAcquisitionChecklist(PimsAcquisitionFile acquisitionFile, ref List<PimsAcquisitionChecklistItem> pimsAcquisitionChecklistItems)
{
var doNotAddToStatuses = new List<string>() { "COMPLT", "CANCEL", "ARCHIV" };
if (doNotAddToStatuses.Contains(acquisitionFile.AcqPhysFileStatusTypeCode))
if (doNotAddToStatuses.Contains(acquisitionFile.AcquisitionFileStatusTypeCode))
{
return;
}
Expand Down
82 changes: 80 additions & 2 deletions source/backend/api/Services/DispositionFileService.cs
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using Microsoft.Extensions.Logging;
using Pims.Api.Constants;
using Pims.Api.Helpers.Exceptions;
using Pims.Core.Exceptions;
using Pims.Core.Extensions;
using Pims.Dal.Constants;
using Pims.Dal.Entities;
using Pims.Dal.Entities.Models;
Expand All @@ -13,6 +15,7 @@
using Pims.Dal.Helpers.Extensions;
using Pims.Dal.Repositories;
using Pims.Dal.Security;
using Pims.Dal.Entities.Extensions;

namespace Pims.Api.Services
{
Expand All @@ -25,6 +28,8 @@
private readonly ICoordinateTransformService _coordinateService;
private readonly IPropertyRepository _propertyRepository;
private readonly IPropertyService _propertyService;
private readonly ILookupRepository _lookupRepository;
private readonly IDispositionFileChecklistRepository _checklistRepository;

public DispositionFileService(
ClaimsPrincipal user,
Expand All @@ -33,7 +38,9 @@
IDispositionFilePropertyRepository dispositionFilePropertyRepository,
ICoordinateTransformService coordinateService,
IPropertyRepository propertyRepository,
IPropertyService propertyService)
IPropertyService propertyService,
ILookupRepository lookupRepository,
IDispositionFileChecklistRepository checklistRepository)
{
_user = user;
_logger = logger;
Expand All @@ -42,6 +49,8 @@
_coordinateService = coordinateService;
_propertyRepository = propertyRepository;
_propertyService = propertyService;
_lookupRepository = lookupRepository;
_checklistRepository = checklistRepository;
}

public PimsDispositionFile Add(PimsDispositionFile dispositionFile, IEnumerable<UserOverrideCode> userOverrides)
Expand Down Expand Up @@ -198,6 +207,49 @@
return _dispositionFileRepository.GetDispositionFileSale(dispositionFileId);
}

public IEnumerable<PimsDispositionChecklistItem> GetChecklistItems(long id)
{
_logger.LogInformation("Getting disposition file checklist with DispositionFile id: {id}", id);
_user.ThrowIfNotAuthorized(Permissions.DispositionView);

var checklistItems = _checklistRepository.GetAllChecklistItemsByDispositionFileId(id);
var dispositionFile = _dispositionFileRepository.GetById(id);
AppendToDispositionChecklist(dispositionFile, ref checklistItems);

return checklistItems;
}

public PimsDispositionFile UpdateChecklistItems(PimsDispositionFile dispositionFile)
{
dispositionFile.ThrowIfNull(nameof(dispositionFile));
_logger.LogInformation("Updating disposition file checklist with DispositionFile id: {id}", dispositionFile.Internal_Id);
_user.ThrowIfNotAuthorized(Permissions.DispositionEdit);

// Get the current checklist items for this disposition file.
var currentItems = _checklistRepository.GetAllChecklistItemsByDispositionFileId(dispositionFile.Internal_Id).ToDictionary(ci => ci.Internal_Id);

foreach (var incomingItem in dispositionFile.PimsDispositionChecklistItems)
{
if (!currentItems.TryGetValue(incomingItem.Internal_Id, out var existingItem) && incomingItem.Internal_Id != 0)
{
throw new BadRequestException($"Cannot update checklist item. Item with Id: {incomingItem.Internal_Id} not found.");
}

// Only update checklist items that changed.
if (existingItem == null)
{
_checklistRepository.Add(incomingItem);
}

Check warning on line 242 in source/backend/api/Services/DispositionFileService.cs

View check run for this annotation

Codecov / codecov/patch

source/backend/api/Services/DispositionFileService.cs#L240-L242

Added lines #L240 - L242 were not covered by tests
else if (existingItem.DspChklstItemStatusTypeCode != incomingItem.DspChklstItemStatusTypeCode)
{
_checklistRepository.Update(incomingItem);
}
}

_checklistRepository.CommitTransaction();
return _dispositionFileRepository.GetById(dispositionFile.Internal_Id);
}

private static void ValidateStaff(PimsDispositionFile dispositionFile)
{
bool duplicate = dispositionFile.PimsDispositionFileTeams.GroupBy(p => p.DspFlTeamProfileTypeCode).Any(g => g.Count() > 1);
Expand All @@ -206,7 +258,7 @@
throw new BadRequestException("Invalid Disposition team, each team member and role combination can only be added once.");
}
}

private static void ValidateDispositionOfferStatus(PimsDispositionFile dispositionFile, PimsDispositionOffer newOffer)
{
bool offerAlreadyAccepted = dispositionFile.PimsDispositionOffers.Any(x => x.DispositionOfferStatusTypeCode == EnumDispositionOfferStatusTypeCode.ACCCEPTED.ToString() && x.DispositionOfferId != newOffer.DispositionOfferId);
Expand Down Expand Up @@ -293,5 +345,31 @@
}
}
}

private void AppendToDispositionChecklist(PimsDispositionFile dispositionFile, ref List<PimsDispositionChecklistItem> pimsDispositionChecklistItems)
{
var doNotAddToStatuses = new List<string>() { "COMPLT", "CANCEL", "ARCHIV" };
if (doNotAddToStatuses.Contains(dispositionFile.DispositionFileStatusTypeCode))
{
return;
}
var checklistStatusTypes = _lookupRepository.GetAllDispositionChecklistItemStatusTypes();
foreach (var itemType in _checklistRepository.GetAllChecklistItemTypes().Where(x => !x.IsExpiredType()))
{
if (!pimsDispositionChecklistItems.Any(cli => cli.DspChklstItemTypeCode == itemType.DspChklstItemTypeCode) && DateOnly.FromDateTime(dispositionFile.AppCreateTimestamp) >= itemType.EffectiveDate)
{
var checklistItem = new PimsDispositionChecklistItem
{
DspChklstItemTypeCode = itemType.DspChklstItemTypeCode,
DspChklstItemTypeCodeNavigation = itemType,
DspChklstItemStatusTypeCode = "INCOMP",
DispositionFileId = dispositionFile.DispositionFileId,
DspChklstItemStatusTypeCodeNavigation = checklistStatusTypes.FirstOrDefault(cst => cst.Id == "INCOMP"),
};

pimsDispositionChecklistItems.Add(checklistItem);
}
}
}
}
}
5 changes: 5 additions & 0 deletions source/backend/api/Services/IDispositionFileService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Pims.Dal.Entities;
using Pims.Dal.Entities.Models;
using Pims.Dal.Exceptions;
using Pims.Dal.Security;

namespace Pims.Api.Services
{
Expand Down Expand Up @@ -30,5 +31,9 @@ public interface IDispositionFileService
bool DeleteDispositionFileOffer(long dispositionFileId, long offerId);

PimsDispositionSale GetDispositionFileSale(long dispositionFileId);

IEnumerable<PimsDispositionChecklistItem> GetChecklistItems(long id);

PimsDispositionFile UpdateChecklistItems(PimsDispositionFile dispositionFile);
}
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Mapster;
using Pims.Api.Models.Base;
using Pims.Api.Models.Models.Concepts.File;
using Entity = Pims.Dal.Entities;

namespace Pims.Api.Models.Concepts.AcquisitionFile
Expand All @@ -8,16 +9,16 @@ public class AcquisitionFileChecklistItemMap : IRegister
{
public void Register(TypeAdapterConfig config)
{
config.NewConfig<Entity.PimsAcquisitionChecklistItem, AcquisitionFileChecklistItemModel>()
config.NewConfig<Entity.PimsAcquisitionChecklistItem, FileChecklistItemModel>()
.Map(dest => dest.Id, src => src.Internal_Id)
.Map(dest => dest.AcquisitionFileId, src => src.AcquisitionFileId)
.Map(dest => dest.FileId, src => src.AcquisitionFileId)
.Map(dest => dest.ItemType, src => src.AcqChklstItemTypeCodeNavigation)
.Map(dest => dest.StatusTypeCode, src => src.AcqChklstItemStatusTypeCodeNavigation)
.Inherits<Entity.IBaseAppEntity, BaseAuditModel>();

config.NewConfig<AcquisitionFileChecklistItemModel, Entity.PimsAcquisitionChecklistItem>()
config.NewConfig<FileChecklistItemModel, Entity.PimsAcquisitionChecklistItem>()
.Map(dest => dest.Internal_Id, src => src.Id)
.Map(dest => dest.AcquisitionFileId, src => src.AcquisitionFileId)
.Map(dest => dest.AcquisitionFileId, src => src.FileId)
.Map(dest => dest.AcqChklstItemTypeCode, src => src.ItemType.Code)
.Map(dest => dest.AcqChklstItemStatusTypeCode, src => src.StatusTypeCode.Id)
.Inherits<BaseAuditModel, Entity.IBaseAppEntity>();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using Mapster;
using Pims.Api.Models.Base;
using Pims.Api.Models.Models.Concepts.File;
using Entity = Pims.Dal.Entities;

namespace Pims.Api.Models.Concepts.AcquisitionFile
Expand All @@ -8,7 +9,7 @@ public class AcquisitionFileChecklistItemTypeMap : IRegister
{
public void Register(TypeAdapterConfig config)
{
config.NewConfig<Entity.PimsAcqChklstItemType, AcquisitionFileChecklistItemTypeModel>()
config.NewConfig<Entity.PimsAcqChklstItemType, FileChecklistItemTypeModel>()
.Map(dest => dest.Code, src => src.Id)
.Map(dest => dest.SectionCode, src => src.ParentId)
.Map(dest => dest.Description, src => src.Description)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public void Register(TypeAdapterConfig config)
.Map(dest => dest.AcquisitionTeam, src => src.PimsAcquisitionFileTeams)
.Map(dest => dest.AcquisitionFileOwners, src => src.PimsAcquisitionOwners)
.Map(dest => dest.AcquisitionFileInterestHolders, src => src.PimsInterestHolders)
.Map(dest => dest.AcquisitionFileChecklist, src => src.PimsAcquisitionChecklistItems)
.Map(dest => dest.FileChecklistItems, src => src.PimsAcquisitionChecklistItems)
.Map(dest => dest.LegacyStakeholders, src => src.GetLegacyInterestHolders())
.Map(dest => dest.CompensationRequisitions, src => src.PimsCompensationRequisitions)
.Inherits<IBaseAppEntity, BaseAuditModel>();
Expand All @@ -61,7 +61,7 @@ public void Register(TypeAdapterConfig config)
.Map(dest => dest.PimsAcquisitionFileTeams, src => src.AcquisitionTeam)
.Map(dest => dest.PimsAcquisitionOwners, src => src.AcquisitionFileOwners)
.Map(dest => dest.PimsInterestHolders, src => src.AcquisitionFileInterestHolders)
.Map(dest => dest.PimsAcquisitionChecklistItems, src => src.AcquisitionFileChecklist)
.Map(dest => dest.PimsAcquisitionChecklistItems, src => src.FileChecklistItems)
.Inherits<BaseAuditModel, IBaseAppEntity>();
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@

namespace Pims.Api.Models.Concepts.AcquisitionFile
{
public class AcquisitionFileModel : FileModel
public class AcquisitionFileModel : FileWithChecklistModel
{
#region Properties

Expand Down Expand Up @@ -113,11 +113,6 @@ public class AcquisitionFileModel : FileModel
/// </summary>
public IList<InterestHolderModel> AcquisitionFileInterestHolders { get; set; }

/// <summary>
/// get/set - A list of acquisition file checklist items.
/// </summary>
public IList<AcquisitionFileChecklistItemModel> AcquisitionFileChecklist { get; set; }

/// <summary>
/// get/set - A list of compensation requisitions related to the acquisition file.
/// </summary>
Expand Down
Loading
Loading