Skip to content

Commit

Permalink
PSP-7013 Enhance Management Summary >> Lease / License Details (#3571)
Browse files Browse the repository at this point in the history
* Update service to return property lease information

* Align frontend api models

* Update lease information on property management update form

* Test corrections
  • Loading branch information
asanchezr authored Nov 4, 2023
1 parent 8996400 commit 3b29ab3
Show file tree
Hide file tree
Showing 10 changed files with 49 additions and 103 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class PropertyManagementModel : BaseAppModel
public string AdditionalDetails { get; set; }

/// <summary>
/// get/set - Whether utilities are payable for this property..
/// get/set - Whether utilities are payable for this property.
/// </summary>
public bool? IsUtilitiesPayable { get; set; }

Expand All @@ -34,17 +34,13 @@ public class PropertyManagementModel : BaseAppModel
public bool? IsTaxesPayable { get; set; }

/// <summary>
/// get/set - Whether this property has an "active lease".
/// get/set - The number of leases for this property. Returns 0 when there are no leases.
/// </summary>
public bool IsLeaseActive { get; set; }
public long RelatedLeases { get; set; }

/// <summary>
/// get/set - Whether this property has an "active lease" that is expired.
/// </summary>
public bool IsLeaseExpired { get; set; }

/// <summary>
/// get/set - The expiry date on the active lease for this property (if any).
/// get/set - The expiry date of the lease when there is only ONE lease for this property (regardless of status).
/// This field is null when the lease does not expire.
/// </summary>
public DateTime? LeaseExpiryDate { get; set; }
}
Expand Down
8 changes: 4 additions & 4 deletions source/backend/api/Services/PropertyService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -179,12 +179,12 @@ public PropertyManagementModel GetPropertyManagement(long propertyId)
var property = GetById(propertyId);

var propertyLeases = _propertyLeaseRepository.GetAllByPropertyId(propertyId);
var activeLease = propertyLeases.FirstOrDefault(pl => pl.Lease.LeaseStatusTypeCode == "ACTIVE")?.Lease;
var leaseExpiryDate = activeLease?.GetExpiryDate()?.FilterSqlMinDate() ?? null;
var leaseCount = propertyLeases.Count();
var firstLease = leaseCount == 1 ? propertyLeases.First().Lease : null;
var leaseExpiryDate = firstLease is not null ? firstLease.GetExpiryDate()?.FilterSqlMinDate() : null;

var propertyManagement = _mapper.Map<PropertyManagementModel>(property);
propertyManagement.IsLeaseActive = activeLease is not null;
propertyManagement.IsLeaseExpired = leaseExpiryDate is not null && (leaseExpiryDate < DateTime.UtcNow);
propertyManagement.RelatedLeases = leaseCount;
propertyManagement.LeaseExpiryDate = leaseExpiryDate;

return propertyManagement;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { forwardRef } from 'react';
import { useMapStateMachine } from '@/components/common/mapFSM/MapStateMachineContext';
import { mockLookups } from '@/mocks/lookups.mock';
import { mapMachineBaseMock } from '@/mocks/mapFSM.mock';
import { getMockApiPropertyManagement } from '@/mocks/propertyManagement.mock';
import { lookupCodesSlice } from '@/store/slices/lookupCodes';
import { render, RenderOptions, waitFor } from '@/utils/test-utils';

Expand Down Expand Up @@ -66,22 +65,10 @@ describe('FilterContentContainer component', () => {
});

it('fetches filter data from the api', async () => {
mockGetApi.execute.mockResolvedValue(getMockApiPropertyManagement(1));
mockGetApi.execute.mockResolvedValue([1, 2]);
setup({});
viewProps.onChange(new PropertyFilterFormModel());
expect(mockGetApi.execute).toBeCalledWith(new PropertyFilterFormModel().toApi());
await waitFor(() =>
expect(mapMachineBaseMock.setVisiblePimsProperties).toBeCalledWith({
additionalDetails: 'test',
id: 1,
isLeaseActive: false,
isLeaseExpired: false,
isTaxesPayable: null,
isUtilitiesPayable: null,
leaseExpiryDate: null,
managementPurposes: [],
rowVersion: 1,
}),
);
await waitFor(() => expect(mapMachineBaseMock.setVisiblePimsProperties).toBeCalledWith([1, 2]));
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ export const PropertyManagementUpdateContainer = React.forwardRef<
additionalDetails: null,
isUtilitiesPayable: null,
isTaxesPayable: null,
isLeaseActive: false,
isLeaseExpired: false,
relatedLeases: 0,
leaseExpiryDate: null,
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export const PropertyManagementUpdateForm = React.forwardRef<
/>
</SectionField>
<SectionField label="Lease/Licensed">
{formikProps.values.formatLeaseInformation()}
{formikProps.values.formattedLeaseInformation ?? ''}
</SectionField>
<SectionField label="Utilities payable">
<YesNoSelect field="isUtilitiesPayable" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ describe('Property management model tests', () => {
expect(model.additionalDetails).toBe('');
expect(model.isTaxesPayable).toBe(null);
expect(model.isUtilitiesPayable).toBe(null);
expect(model.isLeaseActive).toBe(false);
expect(model.leaseExpiryDate).toBe('');
expect(model.formattedLeaseInformation).toBe('No active Lease/License');
});

it('fromApi sets values as expected from api response', () => {
Expand All @@ -36,46 +35,26 @@ describe('Property management model tests', () => {
expect(model.additionalDetails).toBe('test');
expect(model.isTaxesPayable).toBe(null);
expect(model.isUtilitiesPayable).toBe(null);
expect(model.isLeaseActive).toBe(false);
expect(model.leaseExpiryDate).toBe('');
expect(model.formattedLeaseInformation).toBe('No active Lease/License');
});

it('returns default text when no lease information is available', () => {
const model = PropertyManagementFormModel.fromApi(getMockApiPropertyManagement());
expect(model.formatLeaseInformation()).toBe('No active Lease/License');
});

it('returns active lease information and expiry date', () => {
let apiManagement: Api_PropertyManagement = {
...getMockApiPropertyManagement(),
isLeaseActive: true,
leaseExpiryDate: '2020-03-15',
};
const model = PropertyManagementFormModel.fromApi(apiManagement);
expect(model.formatLeaseInformation()).toBe('Yes (Mar 15, 2020)');
});

it('returns expired lease information and expiry date', () => {
let apiManagement: Api_PropertyManagement = {
...getMockApiPropertyManagement(),
isLeaseActive: true,
isLeaseExpired: true,
leaseExpiryDate: '2020-03-15',
};
const model = PropertyManagementFormModel.fromApi(apiManagement);
expect(model.formatLeaseInformation()).toBe('Expired (Mar 15, 2020)');
});

it('returns available lease information without an expiry date', () => {
let apiManagement: Api_PropertyManagement = {
...getMockApiPropertyManagement(),
isLeaseActive: true,
isLeaseExpired: false,
leaseExpiryDate: null,
};
const model = PropertyManagementFormModel.fromApi(apiManagement);
expect(model.formatLeaseInformation()).toBe('Yes');
});
it.each([
['NO lease found', 0, null, 'No active Lease/License'],
['ONE lease with expiry date', 1, '2020-03-15', 'Yes (Mar 15, 2020)'],
['ONE lease with no expiry date', 1, null, 'Yes'],
['MULTIPLE leases', 5, null, 'Multiple'],
])(
'returns lease information as expected - %s',
(_: string, leaseCount: number, expiryDate: string | null, expectedResult: string) => {
let apiManagement: Api_PropertyManagement = {
...getMockApiPropertyManagement(),
relatedLeases: leaseCount,
leaseExpiryDate: expiryDate,
};
const model = PropertyManagementFormModel.fromApi(apiManagement);
expect(model.formattedLeaseInformation).toBe(expectedResult);
},
);

it('toApi converts form values to the api format', () => {
const purpose = new ManagementPurposeModel();
Expand All @@ -96,7 +75,6 @@ describe('Property management model tests', () => {
expect(apiManagement.additionalDetails).toBe('test');
expect(apiManagement.isUtilitiesPayable).toBe(true);
expect(apiManagement.isTaxesPayable).toBe(null);
expect(apiManagement.leaseExpiryDate).toBe(null);
expect(apiManagement.managementPurposes).toHaveLength(1);
expect(apiManagement.managementPurposes[0]).toEqual(
expect.objectContaining({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { Api_PropertyManagement, Api_PropertyManagementPurpose } from '@/models/api/Property';
import { ILookupCode } from '@/store/slices/lookupCodes';
import { prettyFormatDate } from '@/utils';
import { formatApiPropertyManagementLease } from '@/utils';
import { stringToNull } from '@/utils/formUtils';

export class PropertyManagementFormModel {
Expand All @@ -10,9 +10,7 @@ export class PropertyManagementFormModel {
additionalDetails: string = '';
isUtilitiesPayable: boolean | null = null;
isTaxesPayable: boolean | null = null;
isLeaseActive: boolean = false;
isLeaseExpired: boolean = false;
leaseExpiryDate: string | null = null;
formattedLeaseInformation: string | null = null;

static fromApi(base: Api_PropertyManagement | null): PropertyManagementFormModel {
const newFormModel = new PropertyManagementFormModel();
Expand All @@ -23,9 +21,7 @@ export class PropertyManagementFormModel {
newFormModel.additionalDetails = base?.additionalDetails || '';
newFormModel.isUtilitiesPayable = base?.isUtilitiesPayable ?? null;
newFormModel.isTaxesPayable = base?.isTaxesPayable ?? null;
newFormModel.isLeaseActive = base?.isLeaseActive || false;
newFormModel.isLeaseExpired = base?.isLeaseExpired || false;
newFormModel.leaseExpiryDate = base?.leaseExpiryDate || '';
newFormModel.formattedLeaseInformation = formatApiPropertyManagementLease(base);

return newFormModel;
}
Expand All @@ -41,20 +37,10 @@ export class PropertyManagementFormModel {
additionalDetails: stringToNull(this.additionalDetails),
isUtilitiesPayable: this.isUtilitiesPayable,
isTaxesPayable: this.isTaxesPayable,
isLeaseActive: this.isLeaseActive,
isLeaseExpired: this.isLeaseExpired,
leaseExpiryDate: stringToNull(this.leaseExpiryDate),
relatedLeases: 0,
leaseExpiryDate: null,
};
}

formatLeaseInformation(): string {
if (this.isLeaseActive) {
const expiryDate = this.leaseExpiryDate ? `(${prettyFormatDate(this.leaseExpiryDate)})` : '';
return this.isLeaseExpired ? `Expired ${expiryDate}`.trim() : `Yes ${expiryDate}`.trim();
} else {
return 'No active Lease/License';
}
}
}

export class ManagementPurposeModel {
Expand Down
3 changes: 1 addition & 2 deletions source/frontend/src/mocks/propertyManagement.mock.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ export const getMockApiPropertyManagement = (id = 123459): Api_PropertyManagemen
additionalDetails: 'test',
isTaxesPayable: null,
isUtilitiesPayable: null,
isLeaseActive: false,
isLeaseExpired: false,
relatedLeases: 0,
leaseExpiryDate: null,
});

Expand Down
3 changes: 1 addition & 2 deletions source/frontend/src/models/api/Property.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,8 +145,7 @@ export interface Api_PropertyManagement extends Api_ConcurrentVersion_Null, Api_
additionalDetails: string | null;
isUtilitiesPayable: boolean | null;
isTaxesPayable: boolean | null;
isLeaseActive: boolean;
isLeaseExpired: boolean;
relatedLeases: number;
leaseExpiryDate: string | null;
}

Expand Down
18 changes: 10 additions & 8 deletions source/frontend/src/utils/propertyUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,14 +97,16 @@ export const formatBcaAddress = (address?: IBcAssessmentSummary['ADDRESSES'][0])
.join(' ');

export function formatApiPropertyManagementLease(base?: Api_PropertyManagement | null): string {
if (!base) {
return '';
}
const count = base?.relatedLeases || 0;
switch (count) {
case 0:
return 'No active Lease/License';

case 1:
const expiryDate = base?.leaseExpiryDate ? `(${prettyFormatDate(base.leaseExpiryDate)})` : '';
return `Yes ${expiryDate}`.trim();

if (base.isLeaseActive) {
const expiryDate = base.leaseExpiryDate ? `(${prettyFormatDate(base.leaseExpiryDate)})` : '';
return base.isLeaseExpired ? `Expired ${expiryDate}`.trim() : `Yes ${expiryDate}`.trim();
} else {
return 'No active Lease/License';
default:
return 'Multiple';
}
}

0 comments on commit 3b29ab3

Please sign in to comment.