Skip to content

Commit

Permalink
Merge branch 'dev' into psp-9351-fix
Browse files Browse the repository at this point in the history
  • Loading branch information
asanchezr authored Oct 24, 2024
2 parents 8d57129 + ea2838d commit 3ce1f04
Show file tree
Hide file tree
Showing 94 changed files with 7,616 additions and 770 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
using Pims.Api.Helpers.Exceptions;
using Pims.Api.Helpers.Extensions;
using Pims.Api.Models.Base;
using Pims.Api.Models.Concepts.Contact;
using Pims.Api.Policies;
using Pims.Api.Services.Interfaces;
using Pims.Dal.Entities.Models;
Expand Down
6 changes: 3 additions & 3 deletions source/backend/api/Pims.Api.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<UserSecretsId>0ef6255f-9ea0-49ec-8c65-c172304b4926</UserSecretsId>
<Version>5.6.0-91.19</Version>
<Version>5.6.0-91.19</Version>
<AssemblyVersion>5.6.0.91</AssemblyVersion>
<Version>5.6.0-92.2</Version>
<Version>5.6.0-92.2</Version>
<AssemblyVersion>5.6.0.92</AssemblyVersion>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<ProjectGuid>16BC0468-78F6-4C91-87DA-7403C919E646</ProjectGuid>
<TargetFramework>net8.0</TargetFramework>
Expand Down
22 changes: 18 additions & 4 deletions source/backend/api/Services/AcquisitionFileService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,11 @@ public PimsAcquisitionFile Update(PimsAcquisitionFile acquisitionFile, IEnumerab
ValidateMinistryRegion(acquisitionFile.Internal_Id, acquisitionFile.RegionCode);
}

if (!userOverrides.Contains(UserOverrideCode.UpdateSubFilesProjectProduct))
{
ValidateSubFileDependency(acquisitionFile);
}

ValidateStaff(acquisitionFile);
ValidateOrganizationStaff(acquisitionFile);

Expand Down Expand Up @@ -567,7 +572,7 @@ public PimsExpropriationPayment AddExpropriationPayment(long acquisitionFileId,
public IList<PimsExpropriationPayment> GetAcquisitionExpropriationPayments(long acquisitionFileId)
{

_logger.LogInformation("Getting Expropiation Payments for acquisition file id: {acquisitionFileId}", acquisitionFileId);
_logger.LogInformation("Getting Expropriation Payments for acquisition file id: {acquisitionFileId}", acquisitionFileId);
_user.ThrowIfNotAuthorized(Permissions.AcquisitionFileView);
_user.ThrowInvalidAccessToAcquisitionFile(_userRepository, _acqFileRepository, acquisitionFileId);

Expand All @@ -576,14 +581,14 @@ public IList<PimsExpropriationPayment> GetAcquisitionExpropriationPayments(long

public List<PimsAcquisitionFile> GetAcquisitionSubFiles(long id)
{
_logger.LogInformation("Fetch acquistion sub-files for fileId: {id}", id);
_logger.LogInformation("Fetch acquisition sub-files for file id: {id}", id);
_user.ThrowIfNotAuthorized(Permissions.AcquisitionFileView);
_user.ThrowInvalidAccessToAcquisitionFile(_userRepository, _acqFileRepository, id);

var currentAcquisitionFile = GetById(id);
if(currentAcquisitionFile.PrntAcquisitionFileId is not null)
if (currentAcquisitionFile.PrntAcquisitionFileId is not null)
{
throw new BadRequestException("Acquistion file should not be a sub-file.");
throw new BadRequestException("Acquisition file should not be a sub-file.");
}

// Limit search results to user's assigned region(s)
Expand Down Expand Up @@ -699,6 +704,15 @@ private void ValidateMinistryRegion(long acqFileId, short updatedRegion)
}
}

private void ValidateSubFileDependency(PimsAcquisitionFile incomingFile)
{
var currentAcquisitionFile = _acqFileRepository.GetById(incomingFile.Internal_Id);
if (currentAcquisitionFile.ProjectId != incomingFile.ProjectId || currentAcquisitionFile.ProductId != incomingFile.ProductId)
{
throw new UserOverrideException(UserOverrideCode.UpdateSubFilesProjectProduct, "This change will be reflected on other related entities - generated documents, sub-files, etc.\n\nDo you want to proceed?");
}
}

private void ValidateDraftsOnComplete(PimsAcquisitionFile incomingFile)
{
var agreements = _agreementRepository.GetAgreementsByAcquisitionFile(incomingFile.AcquisitionFileId);
Expand Down
5 changes: 4 additions & 1 deletion source/backend/api/Services/DocumentSyncService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ public DocumentSyncResponse SyncPimsDocumentTypes(SyncModel model)
{
DocumentType = documentTypeModel.Name,
DocumentTypeDescription = documentTypeModel.Label,
DocumentTypeDefinition = documentTypeModel.Purpose,
DisplayOrder = documentTypeModel.DisplayOrder,
PimsDocumentCategorySubtypes = subcategories,
};
Expand All @@ -178,12 +179,14 @@ public DocumentSyncResponse SyncPimsDocumentTypes(SyncModel model)
var subtypeCodes = matchingDocumentType.PimsDocumentCategorySubtypes.Select(x => x.DocumentCategoryTypeCode).ToList();

var needsLabelUpdate = matchingDocumentType.DocumentTypeDescription != documentTypeModel.Label;
var needsPurposeUpdate = matchingDocumentType.DocumentTypeDefinition != documentTypeModel.Purpose;
var needsCategoryUpdate = !(subtypeCodes.All(documentTypeModel.Categories.Contains) && subtypeCodes.Count == documentTypeModel.Categories.Count);
var needsOrderUpdate = matchingDocumentType.DisplayOrder != documentTypeModel.DisplayOrder;
var needsToBeEnabled = matchingDocumentType.IsDisabled == true;
if (needsLabelUpdate || needsCategoryUpdate || needsOrderUpdate || needsToBeEnabled)
if (needsLabelUpdate || needsPurposeUpdate|| needsCategoryUpdate || needsOrderUpdate || needsToBeEnabled)
{
matchingDocumentType.DocumentTypeDescription = documentTypeModel.Label;
matchingDocumentType.DocumentTypeDefinition = documentTypeModel.Purpose;
matchingDocumentType.PimsDocumentCategorySubtypes = subcategories;
matchingDocumentType.DisplayOrder = documentTypeModel.DisplayOrder;
matchingDocumentType.IsDisabled = false;
Expand Down
5 changes: 5 additions & 0 deletions source/backend/api/Services/LeaseService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,11 @@ public PimsLease Update(PimsLease lease, IEnumerable<UserOverrideCode> userOverr
List<PimsPropertyLease> differenceSet = currentFileProperties.Where(x => !lease.PimsPropertyLeases.Any(y => y.Internal_Id == x.Internal_Id)).ToList();
foreach (var deletedProperty in differenceSet)
{
if (_propertyLeaseRepository.LeaseFilePropertyInCompensationReq(deletedProperty.PropertyLeaseId))
{
throw new BusinessRuleViolationException("Lease File property can not be removed since it's assigned as a property for a compensation requisition");
}

var totalAssociationCount = _propertyRepository.GetAllAssociationsCountById(deletedProperty.PropertyId);
if (totalAssociationCount <= 1)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public void Register(TypeAdapterConfig config)
config.NewConfig<AcquisitionFileModel, PimsAcquisitionFile>()
.PreserveReference(true)
.Map(dest => dest.AcquisitionFileId, src => src.Id)
.Map(dest => dest.PrntAcquisitionFile, src => src.ParentAcquisitionFileId)
.Map(dest => dest.PrntAcquisitionFileId, src => src.ParentAcquisitionFileId)
.Map(dest => dest.FileNo, src => src.FileNo)
.Map(dest => dest.FileNumber, src => src.FileNumber)
.Map(dest => dest.FileName, src => src.FileName)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
using Mapster;
using Entity = Pims.Dal.Entities;
using Model = Pims.Api.Areas.Contact.Models.Search;

namespace Pims.Api.Areas.Contact.Mapping.Search
namespace Pims.Api.Models.Concepts.Contact
{
public class ContactMap : IRegister
public class ContactSummaryMap : IRegister
{
public void Register(TypeAdapterConfig config)
{
config.NewConfig<Entity.PimsContactMgrVw, Model.ContactSummaryModel>()
config.NewConfig<Entity.PimsContactMgrVw, ContactSummaryModel>()
.Map(dest => dest.Id, src => src.Id)
.Map(dest => dest.PersonId, src => src.PersonId)
.Map(dest => dest.Person, src => src.Person)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
namespace Pims.Api.Areas.Contact.Models.Search
using Pims.Api.Models.Concepts.Organization;
using Pims.Api.Models.Concepts.Person;

namespace Pims.Api.Models.Concepts.Contact
{
public class ContactSummaryModel
{
Expand All @@ -14,19 +17,14 @@ public class ContactSummaryModel
/// </summary>
public long? PersonId { get; set; }

public Pims.Api.Models.Concepts.Person.PersonModel Person { get; set; }
public PersonModel Person { get; set; }

/// <summary>
/// get/set - The primary key to identify the organization.
/// </summary>
public long? OrganizationId { get; set; }

public Pims.Api.Models.Concepts.Organization.OrganizationModel Organization { get; set; }

/// <summary>
/// get/set - The concurrency row version.
/// </summary>
public long RowVersion { get; set; }
public OrganizationModel Organization { get; set; }

/// <summary>
/// get/set - Either the person name or the organization name.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public void Register(TypeAdapterConfig config)
.Map(dest => dest.Id, src => src.DocumentTypeId)
.Map(dest => dest.DocumentType, src => src.DocumentType)
.Map(dest => dest.DocumentTypeDescription, src => src.DocumentTypeDescription)
.Map(dest => dest.DocumentTypePurpose, src => src.DocumentTypeDefinition)
.Map(dest => dest.MayanId, src => src.MayanId)
.Map(dest => dest.IsDisabled, src => src.IsDisabled)
.Inherits<Entity.IBaseAppEntity, BaseAuditModel>();
Expand All @@ -20,6 +21,7 @@ public void Register(TypeAdapterConfig config)
.Map(dest => dest.DocumentTypeId, src => src.Id)
.Map(dest => dest.DocumentType, src => src.DocumentType)
.Map(dest => dest.DocumentTypeDescription, src => src.DocumentTypeDescription)
.Map(dest => dest.DocumentTypeDefinition, src => src.DocumentTypePurpose)
.Map(dest => dest.MayanId, src => src.MayanId)
.Inherits<BaseAuditModel, Entity.IBaseAppEntity>();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ public class DocumentTypeModel : BaseAuditModel
/// </summary>
public string DocumentTypeDescription { get; set; }

/// <summary>
/// get/set - The document type purpose.
/// </summary>
public string DocumentTypePurpose { get; set; }

/// <summary>
/// get/set - The document type id in mayan.
/// </summary>
Expand Down
3 changes: 3 additions & 0 deletions source/backend/apimodels/Models/PimsSync/DocumentTypeModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ public class DocumentTypeModel
[JsonPropertyName("label")]
public string Label { get; set; }

[JsonPropertyName("purpose")]
public string Purpose { get; set; }

[JsonPropertyName("metadata_types")]
public IList<DocumentMetadataTypeModel> MetadataTypes { get; set; }

Expand Down
6 changes: 6 additions & 0 deletions source/backend/dal/Exceptions/OverrideExceptions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,11 @@ public static UserOverrideCode DeleteTakeActiveDisposition
get { return new UserOverrideCode("DELETE_TAKE_ACTIVE_DISPOSITION"); }
}

public static UserOverrideCode UpdateSubFilesProjectProduct
{
get { return new UserOverrideCode("UPDATE_SUBFILES_PROJECT_PRODUCT"); }
}

public string Code { get; private set; }

private static List<UserOverrideCode> UserOverrideCodes => new List<UserOverrideCode>()
Expand All @@ -81,6 +86,7 @@ public static UserOverrideCode DeleteTakeActiveDisposition
UserOverrideCode.DeleteCompletedTake,
UserOverrideCode.DeleteLastTake,
UserOverrideCode.DeleteTakeActiveDisposition,
UserOverrideCode.UpdateSubFilesProjectProduct,
};

private UserOverrideCode(string code)
Expand Down
31 changes: 31 additions & 0 deletions source/backend/dal/Helpers/Extensions/AcquisitionFileExtensions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
using Pims.Dal.Entities;

namespace Pims.Dal.Helpers.Extensions
{
public static class AcquisitionFileExtensions
{
/// <summary>
/// Returns the suffix portion of the supplied Acquisition File Number.
/// </summary>
/// <param name="pimsAcquisitionFile">The Acquisition File entity.</param>
/// <returns>The file number suffix (e.g. "1", "2", "3", etc) if it is found, or -1 if it is not.</returns>
public static int GetAcquisitionNumberSuffix(this PimsAcquisitionFile pimsAcquisitionFile)
{
if (pimsAcquisitionFile is null)
{
return -1;
}

int lastIndex = pimsAcquisitionFile.FileNumber.LastIndexOf('-');
if (lastIndex >= 0 && lastIndex < pimsAcquisitionFile.FileNumber.Length - 1)
{
string suffix = pimsAcquisitionFile.FileNumber.Substring(lastIndex + 1);
return int.TryParse(suffix, out int number) ? number : -1;
}
else
{
return -1;
}
}
}
}
64 changes: 58 additions & 6 deletions source/backend/dal/Repositories/AcquisitionFileRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -671,9 +671,23 @@ public PimsAcquisitionFile Add(PimsAcquisitionFile acquisitionFile)
}
}

int nextFileNo = GetNextAcquisitionFileNumberSequenceValue();
acquisitionFile.FileNo = nextFileNo;
acquisitionFile.FileNumber = GenerateAcquisitionNumber(acquisitionFile.RegionCode, nextFileNo);
if (acquisitionFile.PrntAcquisitionFileId is null)
{
// generate file number for "main" files
int nextFileNo = GetNextAcquisitionFileNumberSequenceValue();
acquisitionFile.FileNo = nextFileNo;
acquisitionFile.FileNumber = GenerateAcquisitionNumber(acquisitionFile.RegionCode, nextFileNo, 1);
}
else
{
// generate file number for "sub-files"
var parentFile = Context.PimsAcquisitionFiles.AsNoTracking()
.FirstOrDefault(x => x.AcquisitionFileId == acquisitionFile.PrntAcquisitionFileId) ?? throw new KeyNotFoundException();

int nextSuffix = GetNextSubFileSuffixValue(parentFile.Internal_Id);
acquisitionFile.FileNo = parentFile.FileNo;
acquisitionFile.FileNumber = GenerateAcquisitionNumber(acquisitionFile.RegionCode, parentFile.FileNo, nextSuffix);
}

Context.PimsAcquisitionFiles.Add(acquisitionFile);
return acquisitionFile;
Expand All @@ -695,8 +709,13 @@ public PimsAcquisitionFile Update(PimsAcquisitionFile acquisitionFile)
// PSP-4413 Changing the MOTI region triggers an update to the ACQ File Number
if (existingAcqFile.RegionCode != acquisitionFile.RegionCode)
{
int suffix = existingAcqFile.GetAcquisitionNumberSuffix();
if (suffix < 0)
{
throw new BusinessRuleViolationException("Cannot parse Acquisition File Number suffix.");
}
acquisitionFile.FileNo = existingAcqFile.FileNo;
acquisitionFile.FileNumber = GenerateAcquisitionNumber(acquisitionFile.RegionCode, acquisitionFile.FileNo);
acquisitionFile.FileNumber = GenerateAcquisitionNumber(acquisitionFile.RegionCode, acquisitionFile.FileNo, suffix);
}
else
{
Expand All @@ -705,6 +724,21 @@ public PimsAcquisitionFile Update(PimsAcquisitionFile acquisitionFile)
acquisitionFile.FileNumber = existingAcqFile.FileNumber;
}

// PSP-9268 Changes to Project/Product on the main file need to be propagated to all sub-files
if (existingAcqFile.ProjectId != acquisitionFile.ProjectId || existingAcqFile.ProductId != acquisitionFile.ProductId)
{
var allRegions = Context.PimsRegions.AsNoTracking().Select(r => r.RegionCode).ToHashSet();
var subFiles = GetAcquisitionSubFiles(existingAcqFile.Internal_Id, allRegions);
foreach (var subFile in subFiles)
{
subFile.ProjectId = acquisitionFile.ProjectId;
subFile.ProductId = acquisitionFile.ProductId;
Context.Entry(subFile).State = EntityState.Modified;
Context.Entry(subFile).Property(x => x.ProjectId).IsModified = true;
Context.Entry(subFile).Property(x => x.ProductId).IsModified = true;
}
}

Context.Entry(existingAcqFile).CurrentValues.SetValues(acquisitionFile);
Context.UpdateChild<PimsAcquisitionFile, long, PimsAcquisitionFileTeam, long>(p => p.PimsAcquisitionFileTeams, acquisitionFile.Internal_Id, acquisitionFile.PimsAcquisitionFileTeams.ToArray());
Context.UpdateChild<PimsAcquisitionFile, long, PimsInterestHolder, long>(p => p.PimsInterestHolders, acquisitionFile.Internal_Id, acquisitionFile.PimsInterestHolders.ToArray());
Expand Down Expand Up @@ -798,12 +832,12 @@ public List<PimsAcquisitionFile> GetAcquisitionSubFiles(long acquisitionFileId,
/// The digit base number is unique to the file. Do not pad the number with zeros.
/// </item>
/// <item>
/// Suffix - (ZZ above) The suffix numbers for an Acquisition file defaults to 01.
/// Suffix - (ZZ above) The suffix numbers for an Acquisition file defaults to 01 for "Main Files".
/// </item>
/// </list>
/// </remarks>
/// <returns>The formatted Acquisition File Number.</returns>
private static string GenerateAcquisitionNumber(short prefix, long fileNumber, short suffix = 1)
private static string GenerateAcquisitionNumber(short prefix, long fileNumber, int suffix = 1)
{
return $"{prefix:00}-{fileNumber}-{suffix:00}";
}
Expand All @@ -817,6 +851,24 @@ private int GetNextAcquisitionFileNumberSequenceValue()
return (int)_sequenceRepository.GetNextSequenceValue("dbo.PIMS_ACQUISITION_FILE_NO_SEQ");
}

private int GetNextSubFileSuffixValue(long parentAcquisitionFileId)
{
// To determine the next suffix number we need to grab all sub-files (regardless of any region restriction)
var allRegions = Context.PimsRegions.AsNoTracking().Select(r => r.RegionCode).ToHashSet();

// The suffix numbers for sub-interest files start from "02", and will increment by 1 for sub-sequent file in the order of creation.
var existingSubFiles = GetAcquisitionSubFiles(parentAcquisitionFileId, allRegions);
if (existingSubFiles.Count == 0)
{
return 2;
}
else
{
int latestSuffix = existingSubFiles.Select(x => x.GetAcquisitionNumberSuffix()).Max();
return latestSuffix + 1;
}
}

/// <summary>
/// Generate a common IQueryable for Acquisition Files.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,7 @@ public interface IPropertyLeaseRepository : IRepository<PimsPropertyLease>
IEnumerable<PimsPropertyLease> GetAllByLeaseId(long leaseId);

IEnumerable<PimsPropertyLease> UpdatePropertyLeases(long leaseId, ICollection<PimsPropertyLease> pimsPropertyLeases);

bool LeaseFilePropertyInCompensationReq(long propertyLeaseFileId);
}
}
10 changes: 10 additions & 0 deletions source/backend/dal/Repositories/PropertyLeaseRepository.cs
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,16 @@ public IEnumerable<PimsPropertyLease> UpdatePropertyLeases(long leaseId, ICollec
return GetAllByLeaseId(leaseId);
}

/// <summary>
/// Check the existence of a LeaseProperty assigned to a Lease Compensation Requisition.
/// </summary>
/// <param name="propertyLeaseFileId"></param>
/// <returns>True if exists.</returns>
public bool LeaseFilePropertyInCompensationReq(long propertyLeaseFileId)
{
return Context.PimsPropLeaseCompReqs.Where(x => x.PropertyLeaseId == propertyLeaseFileId).AsNoTracking().Any();
}

#endregion
}
}
Loading

0 comments on commit 3ce1f04

Please sign in to comment.