Skip to content

Commit 675bf60

Browse files
committed
fix: add missing lease statuses to core schema, improve test coverage, and clean up filters
1 parent c2554ba commit 675bf60

File tree

6 files changed

+161
-11
lines changed

6 files changed

+161
-11
lines changed

core/src/services/lease-service/schemas/lease.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ export const Lease = z.object({
1515
leaseNumber: z.string(),
1616
leaseStartDate: z.coerce.date(),
1717
leaseEndDate: z.coerce.date().optional(),
18-
status: z.enum(['Current', 'Upcoming', 'AboutToEnd', 'Ended']),
18+
status: z.enum(['Current', 'Upcoming', 'AboutToEnd', 'Ended', 'PreliminaryTerminated', 'PendingSignature']),
1919
tenantContactIds: z.array(z.string()).optional(),
2020
rentalPropertyId: z.string(),
2121
rentalProperty: z
@@ -139,7 +139,13 @@ export function mapLease(lease: OnecoreTypesLease): z.infer<typeof Lease> {
139139
? 'Upcoming'
140140
: lease.status === 2
141141
? 'AboutToEnd'
142-
: 'Ended',
142+
: lease.status === 3
143+
? 'Ended'
144+
: lease.status === 4
145+
? 'PreliminaryTerminated'
146+
: lease.status === 5
147+
? 'PendingSignature'
148+
: 'Ended',
143149
tenantContactIds: lease.tenantContactIds,
144150
rentalPropertyId: lease.rentalPropertyId,
145151
type: lease.type,

services/leasing/src/services/lease-service/adapters/tenfast/filters.ts

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -79,11 +79,6 @@ export const isPreliminaryTerminated = (lease: TenfastLease): boolean => {
7979
)
8080
}
8181

82-
// TODO: Verify that acceptedByHyresgast and start actually means pending signature.
8382
export const isPendingSignature = (lease: TenfastLease): boolean => {
84-
return (
85-
lease.stage === 'signingInProgress' ||
86-
lease.stage === 'acceptedByHyresgast' ||
87-
lease.stage === 'start'
88-
)
83+
return lease.stage === 'signingInProgress'
8984
}

services/leasing/src/services/lease-service/adapters/xpand/lease-search-adapter.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,6 @@ const STATUS_ENUM_MAP: Record<string, string> = {
1313
[LeaseStatus.Upcoming]: 'upcoming',
1414
[LeaseStatus.AboutToEnd]: 'abouttoend',
1515
[LeaseStatus.Ended]: 'ended',
16-
[LeaseStatus.PreliminaryTerminated]: 'preliminaryterminated',
17-
[LeaseStatus.PendingSignature]: 'pendingsignature',
1816
}
1917

2018
/** Maps normalized status keys to SQL WHERE conditions */

services/leasing/src/services/lease-service/helpers/tenfast.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ const calculateLeaseStatus = (lease: TenfastLease): LeaseStatus => {
1414
const today = new Date()
1515
const { startDate, endDate, stage } = lease
1616

17-
// Check pending signature first (unsigned leases)
17+
// Check pending signature first
1818
if (isPendingSignature(lease)) return LeaseStatus.PendingSignature
1919

2020
// Check preliminary termination

services/leasing/src/services/lease-service/tests/adapters/tenfast/filters.test.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,19 @@ describe(filterByStatus, () => {
5757
expect(filterByStatus(leases, ['preliminary-terminated'])).toEqual([
5858
preliminaryTerminatedLease,
5959
])
60+
61+
// preliminaryCancellation stage should also be classified as preliminary-terminated
62+
const preliminaryCancellationLease = factory.tenfastLease.build({
63+
startDate: sub(new Date(), { days: 1 }),
64+
endDate: add(new Date(), { days: 30 }),
65+
stage: 'preliminaryCancellation',
66+
signed: true,
67+
})
68+
expect(
69+
filterByStatus([preliminaryCancellationLease], [
70+
'preliminary-terminated',
71+
])
72+
).toEqual([preliminaryCancellationLease])
6073
expect(filterByStatus(leases, ['ended'])).toEqual([endedLease])
6174
expect(filterByStatus(leases, ['pending-signature'])).toEqual([
6275
pendingSignatureLease,
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
import { add, sub } from 'date-fns'
2+
import { LeaseStatus } from '@onecore/types'
3+
4+
import { mapToOnecoreLease } from '../../helpers/tenfast'
5+
import * as factory from '../factories'
6+
7+
describe('calculateLeaseStatus (via mapToOnecoreLease)', () => {
8+
it('returns PendingSignature for signingInProgress stage', () => {
9+
const lease = factory.tenfastLease.build({
10+
stage: 'signingInProgress',
11+
signed: false,
12+
startDate: sub(new Date(), { days: 1 }),
13+
endDate: null,
14+
})
15+
16+
expect(mapToOnecoreLease(lease).status).toBe(LeaseStatus.PendingSignature)
17+
})
18+
19+
it('returns PreliminaryTerminated for requestedCancellation stage', () => {
20+
const lease = factory.tenfastLease.build({
21+
stage: 'requestedCancellation',
22+
signed: true,
23+
startDate: sub(new Date(), { days: 30 }),
24+
endDate: add(new Date(), { days: 30 }),
25+
})
26+
27+
expect(mapToOnecoreLease(lease).status).toBe(
28+
LeaseStatus.PreliminaryTerminated
29+
)
30+
})
31+
32+
it('returns PreliminaryTerminated for preliminaryCancellation stage', () => {
33+
const lease = factory.tenfastLease.build({
34+
stage: 'preliminaryCancellation',
35+
signed: true,
36+
startDate: sub(new Date(), { days: 30 }),
37+
endDate: add(new Date(), { days: 30 }),
38+
})
39+
40+
expect(mapToOnecoreLease(lease).status).toBe(
41+
LeaseStatus.PreliminaryTerminated
42+
)
43+
})
44+
45+
it('returns Ended for cancelled lease with past end date', () => {
46+
const lease = factory.tenfastLease.build({
47+
stage: 'cancelled',
48+
signed: true,
49+
startDate: sub(new Date(), { days: 60 }),
50+
endDate: sub(new Date(), { days: 1 }),
51+
})
52+
53+
expect(mapToOnecoreLease(lease).status).toBe(LeaseStatus.Ended)
54+
})
55+
56+
it('returns Ended for archived lease with past end date', () => {
57+
const lease = factory.tenfastLease.build({
58+
stage: 'archived',
59+
signed: true,
60+
startDate: sub(new Date(), { days: 60 }),
61+
endDate: sub(new Date(), { days: 1 }),
62+
})
63+
64+
expect(mapToOnecoreLease(lease).status).toBe(LeaseStatus.Ended)
65+
})
66+
67+
it('returns AboutToEnd for lease with future end date', () => {
68+
const lease = factory.tenfastLease.build({
69+
stage: 'cancelled',
70+
signed: true,
71+
startDate: sub(new Date(), { days: 30 }),
72+
endDate: add(new Date(), { days: 30 }),
73+
})
74+
75+
expect(mapToOnecoreLease(lease).status).toBe(LeaseStatus.AboutToEnd)
76+
})
77+
78+
it('returns Upcoming for signed lease with future start date', () => {
79+
const lease = factory.tenfastLease.build({
80+
stage: 'signed',
81+
signed: true,
82+
startDate: add(new Date(), { days: 1 }),
83+
endDate: null,
84+
})
85+
86+
expect(mapToOnecoreLease(lease).status).toBe(LeaseStatus.Upcoming)
87+
})
88+
89+
it('returns Current for signed lease with past start date and no end date', () => {
90+
const lease = factory.tenfastLease.build({
91+
stage: 'signed',
92+
signed: true,
93+
startDate: sub(new Date(), { days: 30 }),
94+
endDate: null,
95+
})
96+
97+
expect(mapToOnecoreLease(lease).status).toBe(LeaseStatus.Current)
98+
})
99+
100+
it('returns Current as fallback for unexpected stage', () => {
101+
const lease = factory.tenfastLease.build({
102+
stage: 'unknownStage',
103+
signed: false,
104+
startDate: sub(new Date(), { days: 30 }),
105+
endDate: null,
106+
})
107+
108+
expect(mapToOnecoreLease(lease).status).toBe(LeaseStatus.Current)
109+
})
110+
111+
it('prioritizes PendingSignature over other statuses', () => {
112+
// A signingInProgress lease with a future end date could match AboutToEnd,
113+
// but PendingSignature should take priority
114+
const lease = factory.tenfastLease.build({
115+
stage: 'signingInProgress',
116+
signed: false,
117+
startDate: sub(new Date(), { days: 1 }),
118+
endDate: add(new Date(), { days: 30 }),
119+
})
120+
121+
expect(mapToOnecoreLease(lease).status).toBe(LeaseStatus.PendingSignature)
122+
})
123+
124+
it('prioritizes PreliminaryTerminated over AboutToEnd', () => {
125+
// A requestedCancellation lease with a future end date could match AboutToEnd,
126+
// but PreliminaryTerminated should take priority
127+
const lease = factory.tenfastLease.build({
128+
stage: 'requestedCancellation',
129+
signed: true,
130+
startDate: sub(new Date(), { days: 1 }),
131+
endDate: add(new Date(), { days: 30 }),
132+
})
133+
134+
expect(mapToOnecoreLease(lease).status).toBe(
135+
LeaseStatus.PreliminaryTerminated
136+
)
137+
})
138+
})

0 commit comments

Comments
 (0)