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-8316 | Lease consultation updates #4281

Merged
merged 9 commits into from
Aug 27, 2024
183 changes: 183 additions & 0 deletions source/backend/api/Areas/Leases/Controllers/ConsultationController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@

using System;
using System.Collections.Generic;
using MapsterMapper;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Pims.Api.Helpers.Exceptions;
using Pims.Api.Models.Concepts.Lease;
using Pims.Api.Policies;
using Pims.Api.Services;
using Pims.Core.Extensions;
using Pims.Core.Json;
using Pims.Dal.Security;
using Swashbuckle.AspNetCore.Annotations;

namespace Pims.Api.Areas.Lease.Controllers
{
/// <summary>
/// ConsultationController class, provides endpoints for interacting with lease files consultation.
/// </summary>
[Authorize]
[ApiController]
[ApiVersion("1.0")]
[Area("leases")]
[Route("v{version:apiVersion}/[area]")]
[Route("[area]")]
public class ConsultationController : ControllerBase
{
#region Variables
private readonly ILeaseService _leaseService;
private readonly IMapper _mapper;
private readonly ILogger _logger;

#endregion

#region Constructors

/// <summary>
/// Creates a new instance of a ConsultationController class, initializes it with the specified arguments.
/// </summary>
/// <param name="leaseService"></param>
/// <param name="mapper"></param>
/// <param name="logger"></param>
public ConsultationController(ILeaseService leaseService, IMapper mapper, ILogger<ConsultationController> logger)
{
_leaseService = leaseService;
_mapper = mapper;
_logger = logger;
}
#endregion

#region Endpoints

/// <summary>
/// Get the lease file consultation.
/// </summary>
/// <returns>The consultation items.</returns>
[HttpGet("{id:long}/consultations")]
[HasPermission(Permissions.LeaseView)]
[Produces("application/json")]
[ProducesResponseType(typeof(IEnumerable<ConsultationLeaseModel>), 200)]
[SwaggerOperation(Tags = new[] { "leasefile" })]
public IActionResult GetLeaseConsultations([FromRoute] long id)
{
_logger.LogInformation(
"Request received by Controller: {Controller}, Action: {ControllerAction}, User: {User}, DateTime: {DateTime}",
nameof(ConsultationController),
nameof(GetLeaseConsultations),
User.GetUsername(),
DateTime.Now);

var consultation = _leaseService.GetConsultations(id);
return new JsonResult(_mapper.Map<IEnumerable<ConsultationLeaseModel>>(consultation));
}

/// <summary>
/// Create the lease file consultation to the lease file.
/// </summary>
/// <returns>The consultation items.</returns>
[HttpPost("{id:long}/consultations")]
[HasPermission(Permissions.LeaseView)]
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LeaseEdit?

[Produces("application/json")]
[ProducesResponseType(typeof(ConsultationLeaseModel), 201)]
[TypeFilter(typeof(NullJsonResultFilter))]
[SwaggerOperation(Tags = new[] { "leasefile" })]
public IActionResult AddLeaseConsultation([FromRoute] long id, [FromBody] ConsultationLeaseModel consultation)
{
_logger.LogInformation(
"Request received by Controller: {Controller}, Action: {ControllerAction}, User: {User}, DateTime: {DateTime}",
nameof(ConsultationController),
nameof(AddLeaseConsultation),
User.GetUsername(),
DateTime.Now);

if (id != consultation.LeaseId)
{
throw new BadRequestException("Invalid LeaseId.");
}

var newConsultation = _leaseService.AddConsultation(id, _mapper.Map<Dal.Entities.PimsLeaseConsultation>(consultation));

return new JsonResult(_mapper.Map<ConsultationLeaseModel>(newConsultation));
}

/// <summary>
/// Get the lease file consultation by Id.
/// </summary>
/// <returns>The consultation items.</returns>
[HttpGet("{id:long}/consultations/{consultationId:long}")]
[HasPermission(Permissions.LeaseView)]
[Produces("application/json")]
[ProducesResponseType(typeof(ConsultationLeaseModel), 200)]
[SwaggerOperation(Tags = new[] { "leasefile" })]
public IActionResult GetLeaseConsultationById([FromRoute]long id, [FromRoute]long consultationId)
{
_logger.LogInformation(
"Request received by Controller: {Controller}, Action: {ControllerAction}, User: {User}, DateTime: {DateTime}",
nameof(ConsultationController),
nameof(GetLeaseConsultationById),
User.GetUsername(),
DateTime.Now);

var consultation = _leaseService.GetConsultationById(consultationId);

return new JsonResult(_mapper.Map<ConsultationLeaseModel>(consultation));
}

/// <summary>
/// Update the lease file consultation by Id.
/// </summary>
/// <returns>The consultation item updated.</returns>
[HttpPut("{id:long}/consultations/{consultationId:long}")]
[HasPermission(Permissions.LeaseEdit)]
[Produces("application/json")]
[ProducesResponseType(typeof(ConsultationLeaseModel), 200)]
[TypeFilter(typeof(NullJsonResultFilter))]
[SwaggerOperation(Tags = new[] { "leasefile" })]
public IActionResult UpdateLeaseConsultation([FromRoute] long id, [FromRoute] long consultationId, [FromBody] ConsultationLeaseModel consultation)
{
_logger.LogInformation(
"Request received by Controller: {Controller}, Action: {ControllerAction}, User: {User}, DateTime: {DateTime}",
nameof(ConsultationController),
nameof(UpdateLeaseConsultation),
User.GetUsername(),
DateTime.Now);

if (id != consultation.LeaseId)
{
throw new BadRequestException("Invalid LeaseId.");
}

var updatedConsultation = _leaseService.UpdateConsultation(_mapper.Map<Dal.Entities.PimsLeaseConsultation>(consultation));

return new JsonResult(_mapper.Map<ConsultationLeaseModel>(updatedConsultation));
}

/// <summary>
/// Delete the lease file consultation by Id.
/// </summary>
/// <returns>The consultation item updated.</returns>
[HttpDelete("{id:long}/consultations/{consultationId:long}")]
[HasPermission(Permissions.LeaseView)]
[Produces("application/json")]
[ProducesResponseType(typeof(bool), 200)]
[SwaggerOperation(Tags = new[] { "leasefile" })]
public IActionResult DeleteLeaseConsultation([FromRoute] long id, [FromRoute] long consultationId)
{
_logger.LogInformation(
"Request received by Controller: {Controller}, Action: {ControllerAction}, User: {User}, DateTime: {DateTime}",
nameof(ConsultationController),
nameof(DeleteLeaseConsultation),
User.GetUsername(),
DateTime.Now);

var result = _leaseService.DeleteConsultation(consultationId);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not sure if it matters, but:

  1. the lease id is unused.
  2. the other endpoints validate that the lease id passed is valid for the given consultationId.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, I have added validation to all the routes


return new JsonResult(result);
}

#endregion
}
}
10 changes: 10 additions & 0 deletions source/backend/api/Services/ILeaseService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,15 @@ public interface ILeaseService
PimsLease UpdateChecklistItems(long leaseId, IList<PimsLeaseChecklistItem> checklistItems);

IEnumerable<PimsLeaseStakeholderType> GetAllStakeholderTypes();

IEnumerable<PimsLeaseConsultation> GetConsultations(long leaseId);

PimsLeaseConsultation GetConsultationById(long consultationId);

PimsLeaseConsultation AddConsultation(long leaseId, PimsLeaseConsultation consultation);

PimsLeaseConsultation UpdateConsultation(PimsLeaseConsultation consultation);

bool DeleteConsultation(long consultationId);
}
}
53 changes: 51 additions & 2 deletions source/backend/api/Services/LeaseService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ public class LeaseService : BaseService, ILeaseService
private readonly IInsuranceRepository _insuranceRepository;
private readonly ILeaseStakeholderRepository _stakeholderRepository;
private readonly ILeaseRenewalRepository _renewalRepository;
private readonly IConsultationRepository _consultationRepository;
private readonly IUserRepository _userRepository;
private readonly IPropertyService _propertyService;
private readonly ILookupRepository _lookupRepository;
Expand All @@ -48,6 +49,7 @@ public LeaseService(
IInsuranceRepository insuranceRepository,
ILeaseStakeholderRepository stakeholderRepository,
ILeaseRenewalRepository renewalRepository,
IConsultationRepository consultationRepository,
IUserRepository userRepository,
IPropertyService propertyService,
ILookupRepository lookupRepository)
Expand All @@ -63,6 +65,7 @@ public LeaseService(
_insuranceRepository = insuranceRepository;
_stakeholderRepository = stakeholderRepository;
_renewalRepository = renewalRepository;
_consultationRepository = consultationRepository;
_userRepository = userRepository;
_propertyService = propertyService;
_lookupRepository = lookupRepository;
Expand Down Expand Up @@ -254,8 +257,6 @@ public PimsLease Update(PimsLease lease, IEnumerable<UserOverrideCode> userOverr

_propertyLeaseRepository.UpdatePropertyLeases(lease.Internal_Id, leaseWithProperties.PimsPropertyLeases);

_leaseRepository.UpdateLeaseConsultations(lease.Internal_Id, lease.ConcurrencyControlNumber, lease.PimsLeaseConsultations);

_leaseRepository.UpdateLeaseRenewals(lease.Internal_Id, lease.ConcurrencyControlNumber, lease.PimsLeaseRenewals);

List<PimsPropertyLease> differenceSet = currentFileProperties.Where(x => !lease.PimsPropertyLeases.Any(y => y.Internal_Id == x.Internal_Id)).ToList();
Expand Down Expand Up @@ -340,6 +341,54 @@ public IEnumerable<PimsLeaseStakeholderType> GetAllStakeholderTypes()
return _leaseRepository.GetAllLeaseStakeholderTypes();
}

public IEnumerable<PimsLeaseConsultation> GetConsultations(long leaseId)
{
_logger.LogInformation("Getting lease consultations with Lease id: {leaseId}", leaseId);
_user.ThrowIfNotAuthorized(Permissions.LeaseView);

return _consultationRepository.GetConsultationsByLease(leaseId);
}

public PimsLeaseConsultation GetConsultationById(long consultationId)
{
_logger.LogInformation("Getting consultation with id: {consultationId}", consultationId);
_user.ThrowIfNotAuthorized(Permissions.LeaseEdit);

return _consultationRepository.GetConsultationById(consultationId);
}

public PimsLeaseConsultation AddConsultation(long leaseId, PimsLeaseConsultation consultation)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

unused param.

{
_user.ThrowIfNotAuthorized(Permissions.LeaseEdit);

var newConsultation = _consultationRepository.AddConsultation(consultation);
_consultationRepository.CommitTransaction();

return newConsultation;
}

public PimsLeaseConsultation UpdateConsultation(PimsLeaseConsultation consultation)
{
_user.ThrowIfNotAuthorized(Permissions.LeaseEdit);

var currentConsultation = _consultationRepository.GetConsultationById(consultation.LeaseConsultationId);

var updatedConsultation = _consultationRepository.UpdateConsultation(consultation);
_consultationRepository.CommitTransaction();

return updatedConsultation;
}

public bool DeleteConsultation(long consultationId)
{
_user.ThrowIfNotAuthorized(Permissions.LeaseEdit);

bool deleteResult = _consultationRepository.TryDeleteConsultation(consultationId);
_consultationRepository.CommitTransaction();

return deleteResult;
}

private static void ValidateRenewalDates(PimsLease lease, ICollection<PimsLeaseRenewal> renewals)
{
if (lease.LeaseStatusTypeCode != PimsLeaseStatusTypes.ACTIVE)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
using System;
using Mapster;
using Pims.Api.Models.Base;
using Pims.Core.Extensions;
using Entity = Pims.Dal.Entities;

namespace Pims.Api.Models.Concepts.Deposit
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.Core.Extensions;
using Pims.Dal.Entities;

namespace Pims.Api.Models.Concepts.Lease
Expand All @@ -10,18 +11,38 @@ public void Register(TypeAdapterConfig config)
{
config.NewConfig<PimsLeaseConsultation, ConsultationLeaseModel>()
.Map(dest => dest.Id, src => src.LeaseConsultationId)
.Map(dest => dest.ConsultationType, src => src.ConsultationTypeCodeNavigation)
.Map(dest => dest.ConsultationStatusType, src => src.ConsultationStatusTypeCodeNavigation)
.Map(dest => dest.ParentLeaseId, src => src.LeaseId)
.Map(dest => dest.LeaseId, src => src.LeaseId)
.Map(dest => dest.Lease, src => src.Lease)
.Map(dest => dest.PersonId, src => src.PersonId)
.Map(dest => dest.Person, src => src.Person)
.Map(dest => dest.OrganizationId, src => src.OrganizationId)
.Map(dest => dest.Organization, src => src.Organization)
.Map(dest => dest.PrimaryContactId, src => src.PrimaryContactId)
.Map(dest => dest.PrimaryContact, src => src.PrimaryContact)
.Map(dest => dest.ConsultationTypeCode, src => src.ConsultationTypeCodeNavigation)
.Map(dest => dest.ConsultationStatusTypeCode, src => src.ConsultationStatusTypeCodeNavigation)
.Map(dest => dest.OtherDescription, src => src.OtherDescription)
.Map(dest => dest.RequestedOn, src => src.RequestedOn.ToNullableDateOnly())
.Map(dest => dest.IsResponseReceived, src => src.IsResponseReceived)
.Map(dest => dest.ResponseReceivedDate, src => src.ResponseReceivedDate.ToNullableDateOnly())
.Map(dest => dest.Comment, src => src.Comment)
.Inherits<IBaseAppEntity, BaseAuditModel>();

config.NewConfig<ConsultationLeaseModel, PimsLeaseConsultation>()
.Map(dest => dest.LeaseConsultationId, src => src.Id)
.Map(dest => dest.LeaseId, src => src.ParentLeaseId)
.Map(dest => dest.ConsultationTypeCode, src => src.ConsultationType.Id)
.Map(dest => dest.ConsultationStatusTypeCode, src => src.ConsultationStatusType.Id)
.Map(dest => dest.LeaseId, src => src.LeaseId)
.Map(dest => dest.PersonId, src => src.PersonId)
.Map(dest => dest.OrganizationId, src => src.OrganizationId)
.Map(dest => dest.Organization, src => src.Organization)
.Map(dest => dest.PrimaryContactId, src => src.PrimaryContactId)
.Map(dest => dest.PrimaryContact, src => src.PrimaryContact)
.Map(dest => dest.ConsultationTypeCode, src => src.ConsultationTypeCode.Id)
.Map(dest => dest.ConsultationStatusTypeCode, src => src.ConsultationStatusTypeCode.Id)
.Map(dest => dest.OtherDescription, src => src.OtherDescription)
.Map(dest => dest.RequestedOn, src => src.RequestedOn.ToNullableDateTime())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this a DateOnly or a DateTime?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Its a datetime, however we only need dates, that's wh y the model changes it

.Map(dest => dest.IsResponseReceived, src => src.IsResponseReceived)
.Map(dest => dest.ResponseReceivedDate, src => src.ResponseReceivedDate.ToNullableDateTime())
.Map(dest => dest.Comment, src => src.Comment)
.Inherits<BaseAuditModel, IBaseAppEntity>();
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
using System;
using Pims.Api.Models.Base;
using Pims.Api.Models.Concepts.Organization;
using Pims.Api.Models.Concepts.Person;

namespace Pims.Api.Models.Concepts.Lease
{
Expand All @@ -8,14 +11,35 @@ public class ConsultationLeaseModel : BaseAuditModel

public long Id { get; set; }

public CodeTypeModel<string> ConsultationType { get; set; }
public long LeaseId { get; set; }

public CodeTypeModel<string> ConsultationStatusType { get; set; }
public LeaseModel Lease { get; set; }

public long ParentLeaseId { get; set; }
public long? PersonId { get; set; }

public PersonModel Person { get; set; }

public long? OrganizationId { get; set; }

public OrganizationModel Organization { get; set; }

public long? PrimaryContactId { get; set; }

public PersonModel PrimaryContact { get; set; }

public CodeTypeModel<string> ConsultationTypeCode { get; set; }

public CodeTypeModel<string> ConsultationStatusTypeCode { get; set; }

public string OtherDescription { get; set; }

public DateOnly? RequestedOn { get; set; }

public bool? IsResponseReceived { get; set; }

public DateOnly? ResponseReceivedDate { get; set; }

public string Comment { get; set; }
#endregion
}
}
Loading
Loading