Skip to content

Commit

Permalink
psp-6984 add support for activity documents (#3554)
Browse files Browse the repository at this point in the history
* psp-6984 add support for activity documents

* code review comments.

* adding missing role controller.

* test corrections.
  • Loading branch information
devinleighsmith authored Oct 31, 2023
1 parent e523411 commit bb66979
Show file tree
Hide file tree
Showing 25 changed files with 737 additions and 44 deletions.
17 changes: 17 additions & 0 deletions source/backend/api/Areas/Admin/Controllers/RoleController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,23 @@ public IActionResult GetRoles(int page = 1, int quantity = 10, string name = nul
var result = _mapper.Map<Api.Models.PageModel<Model.RoleModel>>(paged);
return new JsonResult(result);
}

/// <summary>
/// GET - Returns a role for the specified 'key' from the datasource.
/// </summary>
/// <param name="key">The unique 'key' for the role to return.</param>
/// <returns>The role requested.</returns>
[HttpGet("{key}")]
[Produces("application/json")]
[ProducesResponseType(typeof(Model.RoleModel), 200)]
[ProducesResponseType(typeof(Api.Models.ErrorResponseModel), 400)]
[SwaggerOperation(Tags = new[] { "admin-role" })]
public IActionResult GetRole(Guid key)
{
var entity = _roleRepository.GetByKey(key);
var role = _mapper.Map<Model.RoleModel>(entity);
return new JsonResult(role);
}
#endregion
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,10 @@ public IActionResult GetRelationshipDocuments(DocumentRelationType relationshipT
var projectDocuments = _documentFileService.GetFileDocuments<PimsProjectDocument>(FileType.Project, long.Parse(parentId));
var mappedProjectDocuments = _mapper.Map<List<DocumentRelationshipModel>>(projectDocuments);
return new JsonResult(mappedProjectDocuments);
case DocumentRelationType.ManagementFiles:
var managementDocuments = _documentFileService.GetFileDocuments<PimsPropertyActivityDocument>(FileType.Management, long.Parse(parentId));
var mappedPropertyActivityDocuments = _mapper.Map<List<DocumentRelationshipModel>>(managementDocuments);
return new JsonResult(mappedPropertyActivityDocuments);
default:
throw new BadRequestException("Relationship type not valid for retrieve.");
}
Expand Down Expand Up @@ -135,6 +139,7 @@ public async Task<IActionResult> UploadDocumentWithParent(
DocumentRelationType.Templates => await _formDocumentService.UploadFormDocumentTemplateAsync(parentId, uploadRequest),
DocumentRelationType.Projects => await _documentFileService.UploadProjectDocumentAsync(long.Parse(parentId), uploadRequest),
DocumentRelationType.Leases => await _documentFileService.UploadLeaseDocumentAsync(long.Parse(parentId), uploadRequest),
DocumentRelationType.ManagementFiles => await _documentFileService.UploadPropertyActivityDocumentAsync(long.Parse(parentId), uploadRequest),
_ => throw new BadRequestException("Relationship type not valid for upload."),
};

Expand Down Expand Up @@ -176,6 +181,10 @@ public async Task<IActionResult> DeleteDocumentRelationship(DocumentRelationType
var projectRelationship = _mapper.Map<PimsProjectDocument>(model);
var projectResult = await _documentFileService.DeleteProjectDocumentAsync(projectRelationship);
return new JsonResult(projectResult);
case DocumentRelationType.ManagementFiles:
var propertyActivityRelationship = _mapper.Map<PimsPropertyActivityDocument>(model);
var propertyActivityResult = await _documentFileService.DeletePropertyActivityDocumentAsync(propertyActivityRelationship);
return new JsonResult(propertyActivityResult);
default:
throw new BadRequestException("Relationship type not valid for delete.");
}
Expand Down
2 changes: 2 additions & 0 deletions source/backend/api/Constants/DocumentRelationType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,7 @@ public enum DocumentRelationType
Leases,
[EnumMember(Value = "projects")]
Projects,
[EnumMember(Value = "managementfiles")]
ManagementFiles,
}
}
2 changes: 2 additions & 0 deletions source/backend/api/Constants/FileType.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ public enum FileType
Project,
[EnumMember(Value = "lease")]
Lease,
[EnumMember(Value = "management")]
Management,
[EnumMember(Value = "unknown")] // Used in tests/logic only. This does not correspond to a valid file type in the db.
Unknown,
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,20 @@ public void Register(TypeAdapterConfig config)
.Map(dest => dest.FileId, src => src.ParentId)
.Map(dest => dest.DocumentId, src => src.Document.Id)
.Map(dest => dest.Document, src => src.Document);


config.NewConfig<Entity.PimsPropertyActivityDocument, DocumentRelationshipModel>()
.Map(dest => dest.Id, src => src.Internal_Id)
.Map(dest => dest.ParentId, src => src.FileId)
.Map(dest => dest.Document, src => src.Document)
.Map(dest => dest.RelationshipType, src => DocumentRelationType.ManagementFiles)
.Inherits<Entity.IBaseAppEntity, BaseAppModel>();

config.NewConfig<DocumentRelationshipModel, Entity.PimsPropertyActivityDocument>()
.Map(dest => dest.Internal_Id, src => src.Id)
.Map(dest => dest.FileId, src => src.ParentId)
.Map(dest => dest.DocumentId, src => src.Document.Id)
.Map(dest => dest.Document, src => src.Document);
}
}
}
54 changes: 53 additions & 1 deletion source/backend/api/Services/DocumentFileService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ public class DocumentFileService : BaseService, IDocumentFileService
private readonly IProjectRepository _projectRepository;
private readonly IDocumentRepository _documentRepository;
private readonly ILeaseRepository _leaseRepository;
private readonly IPropertyActivityDocumentRepository _propertyActivityDocumentRepository;
private readonly IMapper mapper;

public DocumentFileService(
Expand All @@ -37,7 +38,8 @@ public DocumentFileService(
IMapper mapper,
IProjectRepository projectRepository,
IDocumentRepository documentRepository,
ILeaseRepository leaseRepository)
ILeaseRepository leaseRepository,
IPropertyActivityDocumentRepository propertyActivityDocumentRepository)
: base(user, logger)
{
this.acquisitionFileDocumentRepository = acquisitionFileDocumentRepository;
Expand All @@ -47,6 +49,7 @@ public DocumentFileService(
_projectRepository = projectRepository;
_documentRepository = documentRepository;
_leaseRepository = leaseRepository;
_propertyActivityDocumentRepository = propertyActivityDocumentRepository;
}

public IList<T> GetFileDocuments<T>(FileType fileType, long fileId)
Expand All @@ -69,6 +72,9 @@ public IList<T> GetFileDocuments<T>(FileType fileType, long fileId)
case FileType.Lease:
this.User.ThrowIfNotAuthorized(Permissions.LeaseView);
return _leaseRepository.GetAllLeaseDocuments(fileId).Select(f => f as T).ToArray();
case FileType.Management:
this.User.ThrowIfNotAuthorized(Permissions.ManagementView);
return _propertyActivityDocumentRepository.GetAllByPropertyActivity(fileId).Select(f => f as T).ToArray();
default:
throw new BadRequestException("FileT type not valid to get documents.");
}
Expand Down Expand Up @@ -188,6 +194,34 @@ public async Task<DocumentUploadRelationshipResponse> UploadLeaseDocumentAsync(l
return relationshipResponse;
}

public async Task<DocumentUploadRelationshipResponse> UploadPropertyActivityDocumentAsync(long propertyActivityId, DocumentUploadRequest uploadRequest)
{
this.Logger.LogInformation("Uploading document for single Property Activity");
this.User.ThrowIfNotAuthorized(Permissions.DocumentAdd, Permissions.ManagementEdit);

DocumentUploadResponse uploadResult = await documentService.UploadDocumentAsync(uploadRequest);

DocumentUploadRelationshipResponse relationshipResponse = new()
{
UploadResponse = uploadResult,
};

if (uploadResult.Document.Id != 0)
{
PimsPropertyActivityDocument newDocument = new()
{
PimsPropertyActivityId = propertyActivityId,
DocumentId = uploadResult.Document.Id,
};
newDocument = _propertyActivityDocumentRepository.AddPropertyActivityDocument(newDocument);
_leaseRepository.CommitTransaction();

relationshipResponse.DocumentRelationship = mapper.Map<DocumentRelationshipModel>(newDocument);
}

return relationshipResponse;
}

public async Task<ExternalResult<string>> DeleteResearchDocumentAsync(PimsResearchFileDocument researchFileDocument)
{
this.Logger.LogInformation("Deleting PIMS document for single research file");
Expand Down Expand Up @@ -259,5 +293,23 @@ public async Task<ExternalResult<string>> DeleteLeaseDocumentAsync(PimsLeaseDocu
return new ExternalResult<string>() { Status = ExternalResultStatus.NotExecuted };
}
}

public async Task<ExternalResult<string>> DeletePropertyActivityDocumentAsync(PimsPropertyActivityDocument propertyActivityDocument)
{
this.Logger.LogInformation("Deleting PIMS document for single Property Activity");
this.User.ThrowIfNotAuthorized(Permissions.ManagementDelete);

var relationshipCount = _documentRepository.DocumentRelationshipCount(propertyActivityDocument.DocumentId);
if (relationshipCount == 1)
{
return await documentService.DeleteDocumentAsync(propertyActivityDocument.Document);
}
else
{
_propertyActivityDocumentRepository.DeletePropertyActivityDocument(propertyActivityDocument);
_propertyActivityDocumentRepository.CommitTransaction();
return new ExternalResult<string>() { Status = ExternalResultStatus.NotExecuted };
}
}
}
}
3 changes: 3 additions & 0 deletions source/backend/api/Services/DocumentService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@ public IList<PimsDocumentTyp> GetPimsDocumentTypes(DocumentRelationType relation
case DocumentRelationType.Projects:
categoryType = "PROJECT";
break;
case DocumentRelationType.ManagementFiles:
categoryType = "MANAGEMENT";
break;
default:
throw new InvalidDataException("The requested category relationship does not exist");
}
Expand Down
4 changes: 4 additions & 0 deletions source/backend/api/Services/IDocumentFileService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,16 @@ public IList<T> GetFileDocuments<T>(FileType fileType, long fileId)

Task<DocumentUploadRelationshipResponse> UploadProjectDocumentAsync(long projectId, DocumentUploadRequest uploadRequest);

Task<DocumentUploadRelationshipResponse> UploadPropertyActivityDocumentAsync(long propertyActivityId, DocumentUploadRequest uploadRequest);

Task<ExternalResult<string>> DeleteResearchDocumentAsync(PimsResearchFileDocument researchFileDocument);

Task<ExternalResult<string>> DeleteAcquisitionDocumentAsync(PimsAcquisitionFileDocument acquisitionFileDocument);

Task<ExternalResult<string>> DeleteProjectDocumentAsync(PimsProjectDocument projectDocument);

Task<ExternalResult<string>> DeleteLeaseDocumentAsync(PimsLeaseDocument leaseDocument);

Task<ExternalResult<string>> DeletePropertyActivityDocumentAsync(PimsPropertyActivityDocument propertyActivityDocument);
}
}
1 change: 1 addition & 0 deletions source/backend/api/Startup.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

using System;
using System.Collections.Generic;
using System.Data.SqlClient;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ public static IServiceCollection AddPimsDalRepositories(this IServiceCollection
repositories.AddScoped<Repositories.IExpropriationPaymentRepository, Repositories.ExpropriationPaymentRepository>();
repositories.AddScoped<Repositories.IPropertyContactRepository, Repositories.PropertyContactRepository>();
repositories.AddScoped<Repositories.IPropertyActivityRepository, Repositories.PropertyActivityRepository>();
repositories.AddScoped<Repositories.IPropertyActivityDocumentRepository, Repositories.PropertyActivityDocumentRepository>();
return repositories; // TODO: PSP-4424 Use reflection to find all Repositories.
}

Expand Down
10 changes: 9 additions & 1 deletion source/backend/dal/Repositories/DocumentRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ public bool Delete(PimsDocument document)
.Include(d => d.PimsProjectDocuments)
.Include(d => d.PimsFormTypes)
.Include(d => d.PimsLeaseDocuments)
.Include(d => d.PimsPropertyActivityDocuments)
.Where(d => d.DocumentId == document.Internal_Id)
.AsNoTracking()
.FirstOrDefault();
Expand All @@ -118,6 +119,11 @@ public bool Delete(PimsDocument document)
this.Context.PimsLeaseDocuments.Remove(new PimsLeaseDocument() { Internal_Id = pimsLeaseDocument.Internal_Id });
}

foreach (var pimsPropertyActivityDocument in documentToDelete.PimsPropertyActivityDocuments)
{
this.Context.PimsPropertyActivityDocuments.Remove(new PimsPropertyActivityDocument() { Internal_Id = pimsPropertyActivityDocument.Internal_Id });
}

foreach (var pimsFormTypeDocument in documentToDelete.PimsFormTypes)
{
var updatedFormType = pimsFormTypeDocument;
Expand All @@ -139,6 +145,7 @@ public int DocumentRelationshipCount(long documentId)
.Include(d => d.PimsProjectDocuments)
.Include(d => d.PimsFormTypes)
.Include(d => d.PimsLeaseDocuments)
.Include(d => d.PimsPropertyActivityDocuments)
.Where(d => d.DocumentId == documentId)
.AsNoTracking()
.FirstOrDefault();
Expand All @@ -147,7 +154,8 @@ public int DocumentRelationshipCount(long documentId)
documentRelationships.PimsAcquisitionFileDocuments.Count +
documentRelationships.PimsProjectDocuments.Count +
documentRelationships.PimsFormTypes.Count +
documentRelationships.PimsLeaseDocuments.Count;
documentRelationships.PimsLeaseDocuments.Count +
documentRelationships.PimsPropertyActivityDocuments.Count;
}

#endregion
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.Collections.Generic;
using Pims.Dal.Entities;

namespace Pims.Dal.Repositories
{
/// <summary>
/// IPropertyActivityDocumentRepository interface, provides functions to interact with document management files within the datasource.
/// </summary>
public interface IPropertyActivityDocumentRepository : IRepository<PimsPropertyActivityDocument>
{
IList<PimsPropertyActivityDocument> GetAllByPropertyActivity(long propertyActivityId);

PimsPropertyActivityDocument AddPropertyActivityDocument(PimsPropertyActivityDocument propertyActivityDocument);

bool DeletePropertyActivityDocument(PimsPropertyActivityDocument propertyActivityDocument);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Logging;
using Pims.Core.Extensions;
using Pims.Dal.Entities;

namespace Pims.Dal.Repositories
{
/// <summary>
/// PropertyActivityDocumentRepository class, provides a service layer to interact with document activity files within the datasource.
/// </summary>
public class PropertyActivityDocumentRepository : BaseRepository<PimsPropertyActivityDocument>, IPropertyActivityDocumentRepository
{
#region Constructors

/// <summary>
/// Creates a new instance of a PropertyActivityDocumentRepository, and initializes it with the specified arguments.
/// </summary>
/// <param name="dbContext"></param>
/// <param name="user"></param>
/// <param name="logger"></param>
public PropertyActivityDocumentRepository(PimsContext dbContext, ClaimsPrincipal user, ILogger<PropertyActivityDocumentRepository> logger)
: base(dbContext, user, logger)
{
}
#endregion

#region Methods

/// <summary>
/// Get a list of all the document file relationships for a a given property activity.
/// </summary>
/// <returns></returns>
public IList<PimsPropertyActivityDocument> GetAllByPropertyActivity(long propertyActivityId)
{
return this.Context.PimsPropertyActivityDocuments
.Include(ad => ad.Document)
.ThenInclude(d => d.DocumentStatusTypeCodeNavigation)
.Include(ad => ad.Document)
.ThenInclude(d => d.DocumentType)
.Where(ad => ad.PimsPropertyActivityId == propertyActivityId)
.AsNoTracking()
.ToList();
}

/// <summary>
/// Adds the passed property document activity file to the database.
/// </summary>
/// <param name="propertyActivityDocument"></param>
/// <returns></returns>
public PimsPropertyActivityDocument AddPropertyActivityDocument(PimsPropertyActivityDocument propertyActivityDocument)
{
propertyActivityDocument.ThrowIfNull(nameof(propertyActivityDocument));

var newEntry = this.Context.PimsPropertyActivityDocuments.Add(propertyActivityDocument);
if (newEntry.State == EntityState.Added)
{
return newEntry.Entity;
}
else
{
throw new InvalidOperationException("Could not create document");
}
}

/// <summary>
/// Deletes the passed property document activity file in the database.
/// </summary>
/// <param name="propertyActivityDocument"></param>
/// <returns></returns>
public bool DeletePropertyActivityDocument(PimsPropertyActivityDocument propertyActivityDocument)
{
if (propertyActivityDocument == null)
{
throw new ArgumentNullException(nameof(propertyActivityDocument), "propertyActivityDocument cannot be null.");
}

this.Context.PimsPropertyActivityDocuments.Remove(new PimsPropertyActivityDocument() { PropertyActivityDocumentId = propertyActivityDocument.PropertyActivityDocumentId });
return true;
}

#endregion
}
}
16 changes: 16 additions & 0 deletions source/backend/entities/Partials/PropertyActivityDocument.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
using System.ComponentModel.DataAnnotations.Schema;

namespace Pims.Dal.Entities
{
/// <summary>
/// PimsDocument for Property Activities.
/// </summary>
public partial class PimsPropertyActivityDocument : PimsFileDocument, IBaseAppEntity
{
[NotMapped]
public override long Internal_Id { get => PropertyActivityDocumentId; set => PropertyActivityDocumentId = value; }

[NotMapped]
public override long FileId { get => this.PimsPropertyActivityId; set => this.PimsPropertyActivityId = value; }
}
}
Loading

0 comments on commit bb66979

Please sign in to comment.