Skip to content

Commit a2a3a6a

Browse files
authored
Merge pull request #5246 from asanchezr/psp-11135-lat-long-display
PSP-11135 Display Lat/Long Decimal Coordinates as “x/y”
2 parents d66b479 + 5d71107 commit a2a3a6a

52 files changed

Lines changed: 2857 additions & 2384 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

source/backend/api/Areas/Documents/SearchController.cs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
using Pims.Core.Extensions;
1414
using Pims.Core.Json;
1515
using Pims.Core.Security;
16+
using Pims.Dal.Entities;
1617
using Swashbuckle.AspNetCore.Annotations;
1718

1819
namespace Pims.Api.Areas.Documents
@@ -29,12 +30,14 @@ namespace Pims.Api.Areas.Documents
2930
public class SearchController : ControllerBase
3031
{
3132
private readonly IDocumentService _documentService;
33+
private readonly IPropertyService _propertyService;
3234
private readonly IMapper _mapper;
3335
private readonly ILogger _logger;
3436

35-
public SearchController(IDocumentService documentService, IMapper mapper, ILogger<SearchController> logger)
37+
public SearchController(IDocumentService documentService, IPropertyService propertyService, IMapper mapper, ILogger<SearchController> logger)
3638
{
3739
_documentService = documentService;
40+
_propertyService = propertyService;
3841
_mapper = mapper;
3942
_logger = logger;
4043
}
@@ -70,7 +73,36 @@ public IActionResult GetDocuments([FromQuery] DocumentSearchFilterModel filter)
7073
_logger.LogInformation("Dispatching to service: {Service}", _documentService.GetType());
7174
var documents = _documentService.GetPage(filter);
7275

76+
// Transform all properties to lat/long for returned documents that have properties, this is required for the front end to properly display the property locations.
77+
foreach (var document in documents.Items)
78+
{
79+
var propertyDocuments = document.PimsPropertyDocuments ?? new List<PimsPropertyDocument>();
80+
document.PimsPropertyDocuments = TransformAllPropertiesToLatLong(propertyDocuments);
81+
}
82+
7383
return new JsonResult(_mapper.Map<PageModel<DocumentSearchResultModel>>(documents));
7484
}
85+
86+
/// <summary>
87+
/// Returns the spatial location and boundary polygons in lat/long (4326) for a list of document properties.
88+
/// The spatial values will be modified in-place.
89+
/// </summary>
90+
/// <param name="propertyDocuments">The document properties to re-project.</param>
91+
/// <returns>The document properties with transformed spatial locations.</returns>
92+
private ICollection<PimsPropertyDocument> TransformAllPropertiesToLatLong(ICollection<PimsPropertyDocument> propertyDocuments)
93+
{
94+
if (propertyDocuments == null)
95+
{
96+
return propertyDocuments;
97+
}
98+
99+
foreach (var propertyDocument in propertyDocuments)
100+
{
101+
propertyDocument.Property = _propertyService.TransformPropertyToLatLong(propertyDocument.Property);
102+
}
103+
104+
return propertyDocuments;
105+
}
106+
75107
}
76108
}

source/backend/api/Areas/Reports/Controllers/ManagementActivityController.cs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using System.Linq;
34
using Microsoft.AspNetCore.Authorization;
45
using Microsoft.AspNetCore.Mvc;
@@ -13,6 +14,7 @@
1314
using Pims.Core.Api.Policies;
1415
using Pims.Core.Extensions;
1516
using Pims.Core.Security;
17+
using Pims.Dal.Entities;
1618
using Pims.Dal.Entities.Models;
1719
using Swashbuckle.AspNetCore.Annotations;
1820

@@ -30,11 +32,13 @@ namespace Pims.Api.Areas.Reports.Controllers
3032
public class ManagementActivityController : ControllerBase
3133
{
3234
private readonly IManagementActivityService _managementActivityService;
35+
private readonly IPropertyService _propertyService;
3336
private readonly ILogger _logger;
3437

35-
public ManagementActivityController(IManagementActivityService managementActivityService, ILogger<ManagementActivityController> logger)
38+
public ManagementActivityController(IManagementActivityService managementActivityService, IPropertyService propertyService, ILogger<ManagementActivityController> logger)
3639
{
3740
_managementActivityService = managementActivityService;
41+
_propertyService = propertyService;
3842
_logger = logger;
3943
}
4044

@@ -78,6 +82,13 @@ public IActionResult ExportManagementActivitiesOverview([FromBody] ManagementAct
7882
return NoContent();
7983
}
8084

85+
// Transform all properties to lat/long for returned activities that have properties, this is required for the front end to properly display the property locations.
86+
foreach (var activity in allManagementActivities)
87+
{
88+
var activityProperties = activity.PimsManagementActivityProperties ?? new List<PimsManagementActivityProperty>();
89+
activity.PimsManagementActivityProperties = TransformAllPropertiesToLatLong(activityProperties);
90+
}
91+
8192
var reportActivities = allManagementActivities.Select(a => new ManagementActivityOverviewReportModel(a));
8293

8394
return ReportHelper.GenerateExcel(reportActivities, "Management Activities Overview");
@@ -123,9 +134,38 @@ public IActionResult ExportManagementActivityInvoices([FromBody] ManagementActiv
123134
return NoContent();
124135
}
125136

137+
// Transform all properties to lat/long for returned invoices that have properties, this is required for the front end to properly display the property locations.
138+
foreach (var invoice in allInvoices)
139+
{
140+
var activityProperties = invoice.ManagementActivity.PimsManagementActivityProperties ?? new List<PimsManagementActivityProperty>();
141+
invoice.ManagementActivity.PimsManagementActivityProperties = TransformAllPropertiesToLatLong(activityProperties);
142+
}
143+
126144
var reportInvoices = allInvoices.Select(i => new ManagementActivityInvoicesReportModel(i));
127145

128146
return ReportHelper.GenerateExcel(reportInvoices, "Management Activity Invoices");
129147
}
148+
149+
/// <summary>
150+
/// Returns the spatial location and boundary polygons in lat/long (4326) for a list of activity properties.
151+
/// The spatial values will be modified in-place.
152+
/// </summary>
153+
/// <param name="activityProperties">The activity properties to re-project.</param>
154+
/// <returns>The activity properties with transformed spatial locations.</returns>
155+
private ICollection<PimsManagementActivityProperty> TransformAllPropertiesToLatLong(ICollection<PimsManagementActivityProperty> activityProperties)
156+
{
157+
if (activityProperties == null)
158+
{
159+
return activityProperties;
160+
}
161+
162+
foreach (var activityProperty in activityProperties)
163+
{
164+
activityProperty.Property = _propertyService.TransformPropertyToLatLong(activityProperty.Property);
165+
}
166+
167+
return activityProperties;
168+
}
169+
130170
}
131171
}

source/backend/api/Areas/Reports/Controllers/PropertyController.cs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using Pims.Api.Helpers.Extensions;
88
using Pims.Api.Helpers.Reporting;
99
using Pims.Api.Models.Base;
10+
using Pims.Api.Services;
1011
using Pims.Core.Api.Exceptions;
1112
using Pims.Core.Api.Policies;
1213
using Pims.Core.Security;
@@ -29,6 +30,8 @@ public class PropertyController : ControllerBase
2930
{
3031
#region Variables
3132
private readonly IPropertyRepository _propertyRepository;
33+
private readonly IPropertyService _propertyService;
34+
3235
private readonly IMapper _mapper;
3336
#endregion
3437

@@ -38,10 +41,12 @@ public class PropertyController : ControllerBase
3841
/// Creates a new instance of a ReportController class, initializes it with the specified arguments.
3942
/// </summary>
4043
/// <param name="propertyRepository"></param>
44+
/// <param name="propertyService"></param>
4145
/// <param name="mapper"></param>
42-
public PropertyController(IPropertyRepository propertyRepository, IMapper mapper)
46+
public PropertyController(IPropertyRepository propertyRepository, IPropertyService propertyService, IMapper mapper)
4347
{
4448
_propertyRepository = propertyRepository;
49+
_propertyService = propertyService;
4550
_mapper = mapper;
4651
}
4752
#endregion
@@ -98,6 +103,13 @@ public IActionResult ExportProperties([FromBody] Property.Models.Search.Property
98103

99104
filter.Quantity = all ? _propertyRepository.Count() : filter.Quantity;
100105
var page = _propertyRepository.GetPage((PropertyFilter)filter);
106+
107+
// Transform all properties to lat/long for returned invoices that have properties, this is required for the front end to properly display the property locations.
108+
foreach (var propertyVw in page.Items)
109+
{
110+
_propertyService.TransformPropertyVwToLatLong(propertyVw);
111+
}
112+
101113
var report = _mapper.Map<PageModel<Models.Property.PropertyModel>>(page);
102114

103115
return acceptHeader.ToString() switch

source/backend/api/Areas/Reports/Mapping/Lease/LeaseMap.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,8 +32,8 @@ private static void MapLease((Entity.PimsLeasePeriod period, Entity.PimsLease le
3232
dest.AgreementCommencementDate = src.lease.OrigStartDate?.FilterSqlMinDate().ToNullableDateOnly();
3333
dest.AgreementExpiryDate = src.lease.OrigExpiryDate?.FilterSqlMinDate().ToNullableDateOnly();
3434
dest.LeaseAmount = src.period?.PaymentAmount;
35-
dest.Pid = src.property?.Property?.Pid;
36-
dest.Pin = src.property?.Property?.Pin;
35+
dest.Pid = src.property?.Property?.PidFormatted ?? string.Empty;
36+
dest.Pin = src.property?.Property?.Pin.ToString() ?? string.Empty;
3737
dest.TenantName = src.stakeholder?.GetStakeholderName();
3838
}
3939
}

source/backend/api/Areas/Reports/Mapping/Property/PropertyMap.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using Mapster;
2+
using Pims.Core.Helpers;
23
using Entity = Pims.Dal.Entities;
34
using Model = Pims.Api.Areas.Reports.Models.Property;
45

@@ -16,7 +17,7 @@ public void Register(TypeAdapterConfig config)
1617
.Map(dest => dest.Latitude, src => src.Location.Coordinate.Y)
1718
.Map(dest => dest.Longitude, src => src.Location.Coordinate.X)
1819

19-
.Map(dest => dest.PID, src => src.ParcelIdentity)
20+
.Map(dest => dest.PID, src => src.PidFormatted)
2021
.Map(dest => dest.PIN, src => src.Pin)
2122
.Map(dest => dest.LandArea, src => src.LandArea)
2223
.Map(dest => dest.LandLegalDescription, src => src.LandLegalDescription);
@@ -29,7 +30,7 @@ public void Register(TypeAdapterConfig config)
2930
.Map(dest => dest.Latitude, src => src.Location.Coordinate.Y)
3031
.Map(dest => dest.Longitude, src => src.Location.Coordinate.X)
3132

32-
.Map(dest => dest.PID, src => src.PidPadded)
33+
.Map(dest => dest.PID, src => src.PidPadded != null ? PidTranslator.ConvertPIDToDash(src.PidPadded) : string.Empty)
3334
.Map(dest => dest.PIN, src => src.Pin)
3435
.Map(dest => dest.LandArea, src => src.LandArea)
3536
.Map(dest => dest.LandLegalDescription, src => src.LandLegalDescription);

source/backend/api/Areas/Reports/Models/Lease/LeaseModel.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,11 +31,11 @@ public class LeaseModel
3131

3232
[DisplayName("PID")]
3333
[CsvHelper.Configuration.Attributes.Name("PID")]
34-
public int? Pid { get; set; }
34+
public string Pid { get; set; }
3535

3636
[DisplayName("PIN")]
3737
[CsvHelper.Configuration.Attributes.Name("PIN")]
38-
public int? Pin { get; set; }
38+
public string Pin { get; set; }
3939

4040
[DisplayName("Lease Amount")]
4141
[CsvHelper.Configuration.Attributes.Name("Lease Amount")]

source/backend/api/Models/Report/LeasePaymentReportModel.cs

Lines changed: 11 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
using System.ComponentModel;
44
using System.Linq;
55
using Pims.Api.Services;
6-
using Pims.Core.Helpers;
76
using Pims.Dal.Entities;
87
using Pims.Dal.Helpers.Extensions;
98

@@ -190,8 +189,8 @@ public static LeasePaymentReportModel MapFrom(PimsLeasePayment src)
190189
dest.LFileNumber = src.LeasePeriod.Lease?.LFileNo ?? string.Empty;
191190
dest.HistoricalFiles = GetHistoricalFileNumbers(src.LeasePeriod.Lease);
192191
dest.LeaseStatus = src.LeasePeriod.Lease?.LeaseStatusTypeCodeNavigation?.Description ?? string.Empty;
193-
dest.PropertyList = string.Join(",", leaseProperties.Select(lp => GetFallbackPropertyIdentifier(lp)));
194-
dest.TenantList = string.Join(",", leaseTenants.Select(t => GetStakeholderName(t)));
192+
dest.PropertyList = GetPropertiesAsString(leaseProperties);
193+
dest.TenantList = string.Join("|", leaseTenants.Select(t => GetStakeholderName(t)));
195194
dest.PayableOrReceivable = src.LeasePeriod.Lease.LeasePayRvblTypeCodeNavigation?.Description ?? string.Empty;
196195
dest.Program = GetLeaseProgramName(src.LeasePeriod.Lease);
197196
dest.PeriodStart = src.LeasePeriod.PeriodStartDate.ToString("MMMM dd, yyyy");
@@ -219,6 +218,15 @@ private static string GetLastPaymentDate(PimsLease lease)
219218
return lastPayment != null ? lastPayment.PaymentReceivedDate.ToString("MMMM dd, yyyy") : string.Empty;
220219
}
221220

221+
private static string GetPropertiesAsString(ICollection<PimsPropertyLease> leaseProperties)
222+
{
223+
return string.Join("|", leaseProperties
224+
.Where(lp => lp?.Property != null)
225+
.Select(lp => lp.Property.GetPropertyName())
226+
.Where(s => !string.IsNullOrWhiteSpace(s))
227+
.Distinct());
228+
}
229+
222230
private static string GetStakeholderName(PimsLeaseStakeholder stakeholder)
223231
{
224232
if (stakeholder is null)
@@ -258,39 +266,6 @@ private static string GetLeaseProgramName(PimsLease lease)
258266
}
259267
}
260268

261-
private static string GetFallbackPropertyIdentifier(PimsPropertyLease propertyLease)
262-
{
263-
PimsProperty property = propertyLease?.Property;
264-
if (property?.Pid != null)
265-
{
266-
return PidTranslator.ConvertPIDToDash(property.Pid.ToString());
267-
}
268-
269-
if (property?.Pin != null)
270-
{
271-
return property.Pin.ToString();
272-
}
273-
274-
if (property?.Address != null && !string.IsNullOrEmpty(property.Address.StreetAddress1))
275-
{
276-
string[] addressStrings = new string[2] { property.Address.StreetAddress1, property.Address.MunicipalityName };
277-
return $"({string.Join(" ", addressStrings.Where(s => s != null))})";
278-
}
279-
280-
if (!string.IsNullOrEmpty(propertyLease?.Name))
281-
{
282-
return $"({propertyLease.Name})";
283-
}
284-
285-
if (property?.Location != null)
286-
{
287-
return $"({property.Location.Coordinate.X}, {property.Location.Coordinate.Y})";
288-
}
289-
290-
// Fallback if no identifier is available.
291-
return "No Property Identifier";
292-
}
293-
294269
private static string GetHistoricalFileNumbers(PimsLease lease)
295270
{
296271
var properties = lease.PimsPropertyLeases.Select(pl => pl.Property).Where(p => p != null);

source/backend/api/Services/AcquisitionFileService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ public List<AcquisitionFileExportModel> GetAcquisitionFileExport(AcquisitionFilt
123123
MinistryProject = fileProperty.file.Project is not null ? $"{fileProperty.file.Project.Code} {fileProperty.file.Project.Description}" : string.Empty,
124124
CivicAddress = (fileProperty.fp?.Property is not null && fileProperty.fp.Property.Address is not null) ? fileProperty.fp.Property.Address.FormatFullAddressString() : string.Empty,
125125
GeneralLocation = (fileProperty.fp?.Property is not null) ? fileProperty.fp.Property.GeneralLocation : string.Empty,
126-
Pid = fileProperty.fp is not null && fileProperty.fp.Property.Pid.HasValue ? fileProperty.fp.Property.Pid.ToString() : string.Empty,
126+
Pid = fileProperty.fp is not null && fileProperty.fp.Property.PidFormatted != null ? fileProperty.fp.Property.PidFormatted : string.Empty,
127127
Pin = fileProperty.fp is not null && fileProperty.fp.Property.Pin.HasValue ? fileProperty.fp.Property.Pin.ToString() : string.Empty,
128128
AcquisitionFileStatusTypeCode = fileProperty.file.AcquisitionFileStatusTypeCodeNavigation is not null ? fileProperty.file.AcquisitionFileStatusTypeCodeNavigation.Description : string.Empty,
129129
FileFunding = fileProperty.file.AcquisitionFundingTypeCodeNavigation is not null ? fileProperty.file.AcquisitionFundingTypeCodeNavigation.Description : string.Empty,

source/backend/api/Services/DispositionFileService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -474,7 +474,7 @@ public List<DispositionFileExportModel> GetDispositionFileExport(DispositionFilt
474474
MotiRegion = file.RegionCodeNavigation?.Description ?? string.Empty,
475475
TeamMembers = string.Join("|", file.PimsDispositionFileTeams.Select(x => (x.PersonId.HasValue ? x.Person.GetFullName(true) + $" ({x.DspFlTeamProfileTypeCodeNavigation?.Description})" : x.Organization.Name + $" (Role: {x.DspFlTeamProfileTypeCodeNavigation?.Description}, Primary: {x.PrimaryContact?.GetFullName(true) ?? "N/A"})")) ?? Array.Empty<string>()),
476476
CivicAddress = string.Join("|", file.PimsDispositionFileProperties.Select(x => x.Property?.Address?.FormatFullAddressString()).Where(x => x != null)),
477-
Pid = string.Join("|", file.PimsDispositionFileProperties.Select(x => x.Property?.Pid).Where(x => x != null)),
477+
Pid = string.Join("|", file.PimsDispositionFileProperties.Select(x => x.Property?.PidFormatted).Where(x => x != null)),
478478
Pin = string.Join("|", file.PimsDispositionFileProperties.Select(x => x.Property?.Pin).Where(x => x != null)),
479479
GeneralLocation = string.Join("|", file.PimsDispositionFileProperties.Select(x => x.Property?.GeneralLocation).Where(x => x != null)),
480480
DispositionStatusTypeCode = file.DispositionStatusTypeCodeNavigation?.Description ?? string.Empty,

source/backend/api/Services/DocumentService.cs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,7 @@ public DocumentService(
8888
IAvService avService,
8989
IMapper mapper,
9090
IOptionsMonitor<AuthClientOptions> options,
91-
IOptionsMonitor<MayanConfig> mayanOptions,
92-
IDocumentQueueRepository queueRepository)
91+
IOptionsMonitor<MayanConfig> mayanOptions)
9392
: base(user, logger)
9493
{
9594
this.documentRepository = documentRepository;

0 commit comments

Comments
 (0)