@defra-fish/sales-api-service 1.57.0-rc.4 → 1.57.0-rc.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +5 -5
- package/src/services/__tests__/__snapshots__/recurring-payments.service.spec.js.snap +1 -1
- package/src/services/__tests__/recurring-payments.service.spec.js +196 -3
- package/src/services/recurring-payments.service.js +38 -1
- package/src/services/transactions/__tests__/process-transaction-queue.spec.js +43 -1
- package/src/services/transactions/process-transaction-queue.js +4 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@defra-fish/sales-api-service",
|
|
3
|
-
"version": "1.57.0-rc.
|
|
3
|
+
"version": "1.57.0-rc.6",
|
|
4
4
|
"description": "Rod Licensing Sales API",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -35,9 +35,9 @@
|
|
|
35
35
|
"test": "echo \"Error: run tests from root\" && exit 1"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@defra-fish/business-rules-lib": "1.57.0-rc.
|
|
39
|
-
"@defra-fish/connectors-lib": "1.57.0-rc.
|
|
40
|
-
"@defra-fish/dynamics-lib": "1.57.0-rc.
|
|
38
|
+
"@defra-fish/business-rules-lib": "1.57.0-rc.6",
|
|
39
|
+
"@defra-fish/connectors-lib": "1.57.0-rc.6",
|
|
40
|
+
"@defra-fish/dynamics-lib": "1.57.0-rc.6",
|
|
41
41
|
"@hapi/boom": "^9.1.2",
|
|
42
42
|
"@hapi/hapi": "^20.1.3",
|
|
43
43
|
"@hapi/inert": "^6.0.3",
|
|
@@ -52,5 +52,5 @@
|
|
|
52
52
|
"moment-timezone": "^0.5.34",
|
|
53
53
|
"uuid": "^8.3.2"
|
|
54
54
|
},
|
|
55
|
-
"gitHead": "
|
|
55
|
+
"gitHead": "5c21e5443b8224f43c980c6a53746c593196500b"
|
|
56
56
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import { findDueRecurringPayments } from '@defra-fish/dynamics-lib'
|
|
2
|
-
import { getRecurringPayments, processRecurringPayment } from '../recurring-payments.service.js'
|
|
1
|
+
import { findDueRecurringPayments, Permission } from '@defra-fish/dynamics-lib'
|
|
2
|
+
import { getRecurringPayments, processRecurringPayment, generateRecurringPaymentRecord } from '../recurring-payments.service.js'
|
|
3
|
+
import { createHash } from 'node:crypto'
|
|
3
4
|
|
|
4
5
|
jest.mock('@defra-fish/dynamics-lib', () => ({
|
|
5
6
|
...jest.requireActual('@defra-fish/dynamics-lib'),
|
|
@@ -8,6 +9,13 @@ jest.mock('@defra-fish/dynamics-lib', () => ({
|
|
|
8
9
|
findDueRecurringPayments: jest.fn()
|
|
9
10
|
}))
|
|
10
11
|
|
|
12
|
+
jest.mock('node:crypto', () => ({
|
|
13
|
+
createHash: jest.fn(() => ({
|
|
14
|
+
update: () => {},
|
|
15
|
+
digest: () => 'abcdef99987'
|
|
16
|
+
}))
|
|
17
|
+
}))
|
|
18
|
+
|
|
11
19
|
const dynamicsLib = jest.requireMock('@defra-fish/dynamics-lib')
|
|
12
20
|
|
|
13
21
|
const getMockRecurringPayment = () => ({
|
|
@@ -81,6 +89,22 @@ const getMockPermission = () => ({
|
|
|
81
89
|
})
|
|
82
90
|
|
|
83
91
|
describe('recurring payments service', () => {
|
|
92
|
+
const createSimpleSampleTransactionRecord = () => ({ payment: { recurring: true }, permissions: [{}] })
|
|
93
|
+
const createSamplePermission = overrides => {
|
|
94
|
+
const p = new Permission()
|
|
95
|
+
p.referenceNumber = 'ABC123'
|
|
96
|
+
p.issueDate = '2024-12-04T11:15:12Z'
|
|
97
|
+
p.startDate = '2024-12-04T11:45:12Z'
|
|
98
|
+
p.endDate = '2025-12-03T23:59:59.999Z'
|
|
99
|
+
p.stagingId = 'aaa-111-bbb-222'
|
|
100
|
+
p.isRenewal = false
|
|
101
|
+
p.isLicenseForYou = 1
|
|
102
|
+
for (const key in overrides) {
|
|
103
|
+
p[key] = overrides[key]
|
|
104
|
+
}
|
|
105
|
+
return p
|
|
106
|
+
}
|
|
107
|
+
|
|
84
108
|
beforeEach(jest.clearAllMocks)
|
|
85
109
|
describe('getRecurringPayments', () => {
|
|
86
110
|
it('should equal result of findDueRecurringPayments query', async () => {
|
|
@@ -123,7 +147,6 @@ describe('recurring payments service', () => {
|
|
|
123
147
|
cancelledReason: null,
|
|
124
148
|
endDate: new Date('2023-11-12'),
|
|
125
149
|
agreementId: '435678',
|
|
126
|
-
publicId: '1234456',
|
|
127
150
|
status: 0
|
|
128
151
|
}
|
|
129
152
|
},
|
|
@@ -133,5 +156,175 @@ describe('recurring payments service', () => {
|
|
|
133
156
|
const result = await processRecurringPayment(transactionRecord, contact)
|
|
134
157
|
expect(result.recurringPayment).toMatchSnapshot()
|
|
135
158
|
})
|
|
159
|
+
|
|
160
|
+
it.each(['abc-123', 'def-987'])('generates a publicId %s for the recurring payment', async samplePublicId => {
|
|
161
|
+
createHash.mockReturnValue({
|
|
162
|
+
update: () => {},
|
|
163
|
+
digest: () => samplePublicId
|
|
164
|
+
})
|
|
165
|
+
const result = await processRecurringPayment(createSimpleSampleTransactionRecord(), getMockContact())
|
|
166
|
+
expect(result.recurringPayment.publicId).toBe(samplePublicId)
|
|
167
|
+
})
|
|
168
|
+
|
|
169
|
+
it('passes the unique id of the entity to the hash.update function', async () => {
|
|
170
|
+
const update = jest.fn()
|
|
171
|
+
createHash.mockReturnValueOnce({
|
|
172
|
+
update,
|
|
173
|
+
digest: () => {}
|
|
174
|
+
})
|
|
175
|
+
const { recurringPayment } = await processRecurringPayment(createSimpleSampleTransactionRecord(), getMockContact())
|
|
176
|
+
expect(update).toHaveBeenCalledWith(recurringPayment.uniqueContentId)
|
|
177
|
+
})
|
|
178
|
+
|
|
179
|
+
it('hashes using sha256', async () => {
|
|
180
|
+
await processRecurringPayment(createSimpleSampleTransactionRecord(), getMockContact())
|
|
181
|
+
expect(createHash).toHaveBeenCalledWith('sha256')
|
|
182
|
+
})
|
|
183
|
+
|
|
184
|
+
it('uses base64 hash string', async () => {
|
|
185
|
+
const digest = jest.fn()
|
|
186
|
+
createHash.mockReturnValueOnce({
|
|
187
|
+
update: () => {},
|
|
188
|
+
digest
|
|
189
|
+
})
|
|
190
|
+
await processRecurringPayment(createSimpleSampleTransactionRecord(), getMockContact())
|
|
191
|
+
expect(digest).toHaveBeenCalledWith('base64')
|
|
192
|
+
})
|
|
193
|
+
})
|
|
194
|
+
|
|
195
|
+
describe('generateRecurringPaymentRecord', () => {
|
|
196
|
+
const createFinalisedSampleTransaction = (agreementId, permission) => ({
|
|
197
|
+
expires: 1732892402,
|
|
198
|
+
cost: 35.8,
|
|
199
|
+
isRecurringPaymentSupported: true,
|
|
200
|
+
permissions: [
|
|
201
|
+
{
|
|
202
|
+
permitId: 'permit-id-1',
|
|
203
|
+
licensee: {},
|
|
204
|
+
referenceNumber: '23211125-2WC3FBP-ABNDT8',
|
|
205
|
+
isLicenceForYou: true,
|
|
206
|
+
...permission
|
|
207
|
+
}
|
|
208
|
+
],
|
|
209
|
+
agreementId,
|
|
210
|
+
payment: {
|
|
211
|
+
amount: 35.8,
|
|
212
|
+
source: 'Gov Pay',
|
|
213
|
+
method: 'Debit card',
|
|
214
|
+
timestamp: '2024-11-22T15:00:45.922Z'
|
|
215
|
+
},
|
|
216
|
+
id: 'd26d646f-ed0f-4cf1-b6c1-ccfbbd611757',
|
|
217
|
+
dataSource: 'Web Sales',
|
|
218
|
+
transactionId: 'd26d646f-ed0f-4cf1-b6c1-ccfbbd611757',
|
|
219
|
+
status: { id: 'FINALISED' }
|
|
220
|
+
})
|
|
221
|
+
|
|
222
|
+
it.each([
|
|
223
|
+
[
|
|
224
|
+
'same day start - next due on issue date plus one year minus ten days',
|
|
225
|
+
'iujhy7u8ijhy7u8iuuiuu8ie89',
|
|
226
|
+
{
|
|
227
|
+
startDate: '2024-11-22T15:30:45.922Z',
|
|
228
|
+
issueDate: '2024-11-22T15:00:45.922Z',
|
|
229
|
+
endDate: '2025-11-21T23:59:59.999Z'
|
|
230
|
+
},
|
|
231
|
+
'2025-11-12T00:00:00.000Z'
|
|
232
|
+
],
|
|
233
|
+
[
|
|
234
|
+
'next day start - next due on end date minus ten days',
|
|
235
|
+
'89iujhy7u8i87yu9iokjuij901',
|
|
236
|
+
{
|
|
237
|
+
startDate: '2024-11-23T00:00:00.000Z',
|
|
238
|
+
issueDate: '2024-11-22T15:00:45.922Z',
|
|
239
|
+
endDate: '2025-11-22T23:59:59.999Z'
|
|
240
|
+
},
|
|
241
|
+
'2025-11-12T00:00:00.000Z'
|
|
242
|
+
],
|
|
243
|
+
[
|
|
244
|
+
'starts ten days after issue - next due on issue date plus one year',
|
|
245
|
+
'9o8u7yhui89u8i9oiu8i8u7yhu',
|
|
246
|
+
{
|
|
247
|
+
startDate: '2024-11-22T00:00:00.000Z',
|
|
248
|
+
issueDate: '2024-11-12T15:00:45.922Z',
|
|
249
|
+
endDate: '2025-11-21T23:59:59.999Z'
|
|
250
|
+
},
|
|
251
|
+
'2025-11-12T00:00:00.000Z'
|
|
252
|
+
],
|
|
253
|
+
[
|
|
254
|
+
'starts twenty days after issue - next due on issue date plus one year',
|
|
255
|
+
'9o8u7yhui89u8i9oiu8i8u7yhu',
|
|
256
|
+
{
|
|
257
|
+
startDate: '2024-12-01T00:00:00.000Z',
|
|
258
|
+
issueDate: '2024-11-12T15:00:45.922Z',
|
|
259
|
+
endDate: '2025-01-30T23:59:59.999Z'
|
|
260
|
+
},
|
|
261
|
+
'2025-11-12T00:00:00.000Z'
|
|
262
|
+
],
|
|
263
|
+
[
|
|
264
|
+
"issued on 29th Feb '24, starts on 30th March '24 - next due on 28th Feb '25",
|
|
265
|
+
'hy7u8ijhyu78jhyu8iu8hjiujn',
|
|
266
|
+
{
|
|
267
|
+
startDate: '2024-03-30T00:00:00.000Z',
|
|
268
|
+
issueDate: '2024-02-29T12:38:24.123Z',
|
|
269
|
+
endDate: '2025-03-29T23:59:59.999Z'
|
|
270
|
+
},
|
|
271
|
+
'2025-02-28T00:00:00.000Z'
|
|
272
|
+
],
|
|
273
|
+
[
|
|
274
|
+
"issued on 30th March '25 at 1am, starts at 1:30am - next due on 20th March '26",
|
|
275
|
+
'jhy67uijhy67u87yhtgjui8u7j',
|
|
276
|
+
{
|
|
277
|
+
startDate: '2025-03-30T01:30:00.000Z',
|
|
278
|
+
issueDate: '2025-03-30T01:00:00.000Z',
|
|
279
|
+
endDate: '2026-03-29T23:59:59.999Z'
|
|
280
|
+
},
|
|
281
|
+
'2026-03-20T00:00:00.000Z'
|
|
282
|
+
]
|
|
283
|
+
])('creates record from transaction with %s', (_d, agreementId, permissionData, expectedNextDueDate) => {
|
|
284
|
+
const sampleTransaction = createFinalisedSampleTransaction(agreementId, permissionData)
|
|
285
|
+
const permission = createSamplePermission(permissionData)
|
|
286
|
+
|
|
287
|
+
const rpRecord = generateRecurringPaymentRecord(sampleTransaction, permission)
|
|
288
|
+
|
|
289
|
+
expect(rpRecord).toEqual(
|
|
290
|
+
expect.objectContaining({
|
|
291
|
+
payment: expect.objectContaining({
|
|
292
|
+
recurring: expect.objectContaining({
|
|
293
|
+
name: '',
|
|
294
|
+
nextDueDate: expectedNextDueDate,
|
|
295
|
+
cancelledDate: null,
|
|
296
|
+
cancelledReason: null,
|
|
297
|
+
endDate: permissionData.endDate,
|
|
298
|
+
agreementId,
|
|
299
|
+
status: 1
|
|
300
|
+
})
|
|
301
|
+
}),
|
|
302
|
+
permissions: expect.arrayContaining([permission])
|
|
303
|
+
})
|
|
304
|
+
)
|
|
305
|
+
})
|
|
306
|
+
|
|
307
|
+
it.each([
|
|
308
|
+
[
|
|
309
|
+
'start date is thirty one days after issue date',
|
|
310
|
+
{
|
|
311
|
+
startDate: '2024-12-14T00:00:00.000Z',
|
|
312
|
+
issueDate: '2024-11-12T15:00:45.922Z',
|
|
313
|
+
endDate: '2025-12-13T23:59:59.999Z'
|
|
314
|
+
}
|
|
315
|
+
],
|
|
316
|
+
[
|
|
317
|
+
'start date precedes issue date',
|
|
318
|
+
{
|
|
319
|
+
startDate: '2024-11-11T00:00:00.000Z',
|
|
320
|
+
issueDate: '2024-11-12T15:00:45.922Z',
|
|
321
|
+
endDate: '2025-11-10T23:59:59.999Z'
|
|
322
|
+
}
|
|
323
|
+
]
|
|
324
|
+
])('throws an error for invalid dates when %s', (_d, permission) => {
|
|
325
|
+
const sampleTransaction = createFinalisedSampleTransaction('hyu78ijhyu78ijuhyu78ij9iu6', permission)
|
|
326
|
+
|
|
327
|
+
expect(() => generateRecurringPaymentRecord(sampleTransaction)).toThrow('Invalid dates provided for permission')
|
|
328
|
+
})
|
|
136
329
|
})
|
|
137
330
|
})
|
|
@@ -1,22 +1,59 @@
|
|
|
1
1
|
import { executeQuery, findDueRecurringPayments, RecurringPayment } from '@defra-fish/dynamics-lib'
|
|
2
|
+
import { createHash } from 'node:crypto'
|
|
3
|
+
import { ADVANCED_PURCHASE_MAX_DAYS } from '@defra-fish/business-rules-lib'
|
|
4
|
+
import moment from 'moment'
|
|
2
5
|
|
|
3
6
|
export const getRecurringPayments = date => executeQuery(findDueRecurringPayments(date))
|
|
4
7
|
|
|
8
|
+
const getNextDueDate = (startDate, issueDate, endDate) => {
|
|
9
|
+
const mStart = moment(startDate)
|
|
10
|
+
if (mStart.isAfter(moment(issueDate)) && mStart.isSameOrBefore(moment(issueDate).add(ADVANCED_PURCHASE_MAX_DAYS, 'days'), 'day')) {
|
|
11
|
+
if (mStart.isSame(moment(issueDate), 'day')) {
|
|
12
|
+
return moment(startDate).add(1, 'year').subtract(10, 'days').startOf('day').toISOString()
|
|
13
|
+
}
|
|
14
|
+
if (mStart.isBefore(moment(issueDate).add(10, 'days'), 'day')) {
|
|
15
|
+
return moment(endDate).subtract(10, 'days').startOf('day').toISOString()
|
|
16
|
+
}
|
|
17
|
+
return moment(issueDate).add(1, 'year').startOf('day').toISOString()
|
|
18
|
+
}
|
|
19
|
+
throw new Error('Invalid dates provided for permission')
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export const generateRecurringPaymentRecord = (transactionRecord, permission) => {
|
|
23
|
+
const [{ startDate, issueDate, endDate }] = transactionRecord.permissions
|
|
24
|
+
return {
|
|
25
|
+
payment: {
|
|
26
|
+
recurring: {
|
|
27
|
+
name: '',
|
|
28
|
+
nextDueDate: getNextDueDate(startDate, issueDate, endDate),
|
|
29
|
+
cancelledDate: null,
|
|
30
|
+
cancelledReason: null,
|
|
31
|
+
endDate,
|
|
32
|
+
agreementId: transactionRecord.agreementId,
|
|
33
|
+
status: 1
|
|
34
|
+
}
|
|
35
|
+
},
|
|
36
|
+
permissions: [permission]
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
5
40
|
/**
|
|
6
41
|
* Process a recurring payment instruction
|
|
7
42
|
* @param transactionRecord
|
|
8
43
|
* @returns {Promise<{recurringPayment: RecurringPayment | null}>}
|
|
9
44
|
*/
|
|
10
45
|
export const processRecurringPayment = async (transactionRecord, contact) => {
|
|
46
|
+
const hash = createHash('sha256')
|
|
11
47
|
if (transactionRecord.payment?.recurring) {
|
|
12
48
|
const recurringPayment = new RecurringPayment()
|
|
49
|
+
hash.update(recurringPayment.uniqueContentId)
|
|
13
50
|
recurringPayment.name = transactionRecord.payment.recurring.name
|
|
14
51
|
recurringPayment.nextDueDate = transactionRecord.payment.recurring.nextDueDate
|
|
15
52
|
recurringPayment.cancelledDate = transactionRecord.payment.recurring.cancelledDate
|
|
16
53
|
recurringPayment.cancelledReason = transactionRecord.payment.recurring.cancelledReason
|
|
17
54
|
recurringPayment.endDate = transactionRecord.payment.recurring.endDate
|
|
18
55
|
recurringPayment.agreementId = transactionRecord.payment.recurring.agreementId
|
|
19
|
-
recurringPayment.publicId =
|
|
56
|
+
recurringPayment.publicId = hash.digest('base64')
|
|
20
57
|
recurringPayment.status = transactionRecord.payment.recurring.status
|
|
21
58
|
const [permission] = transactionRecord.permissions
|
|
22
59
|
recurringPayment.bindToEntity(RecurringPayment.definition.relationships.activePermission, permission)
|
|
@@ -26,6 +26,7 @@ import { TRANSACTION_STAGING_TABLE, TRANSACTION_STAGING_HISTORY_TABLE } from '..
|
|
|
26
26
|
import AwsMock from 'aws-sdk'
|
|
27
27
|
import { POCL_DATA_SOURCE, DDE_DATA_SOURCE } from '@defra-fish/business-rules-lib'
|
|
28
28
|
import moment from 'moment'
|
|
29
|
+
import { processRecurringPayment, generateRecurringPaymentRecord } from '../../recurring-payments.service.js'
|
|
29
30
|
|
|
30
31
|
jest.mock('../../reference-data.service.js', () => ({
|
|
31
32
|
...jest.requireActual('../../reference-data.service.js'),
|
|
@@ -64,9 +65,12 @@ jest.mock('@defra-fish/business-rules-lib', () => ({
|
|
|
64
65
|
START_AFTER_PAYMENT_MINUTES: 30
|
|
65
66
|
}))
|
|
66
67
|
|
|
68
|
+
jest.mock('../../recurring-payments.service.js')
|
|
69
|
+
|
|
67
70
|
describe('transaction service', () => {
|
|
68
71
|
beforeAll(() => {
|
|
69
72
|
TRANSACTION_STAGING_TABLE.TableName = 'TestTable'
|
|
73
|
+
processRecurringPayment.mockResolvedValue({})
|
|
70
74
|
})
|
|
71
75
|
|
|
72
76
|
beforeEach(jest.clearAllMocks)
|
|
@@ -125,6 +129,7 @@ describe('transaction service', () => {
|
|
|
125
129
|
[
|
|
126
130
|
'licences with a recurring payment',
|
|
127
131
|
() => {
|
|
132
|
+
processRecurringPayment.mockResolvedValueOnce({ recurringPayment: new RecurringPayment() })
|
|
128
133
|
const mockRecord = mockFinalisedTransactionRecord()
|
|
129
134
|
mockRecord.payment.recurring = {
|
|
130
135
|
name: 'Test name',
|
|
@@ -143,9 +148,9 @@ describe('transaction service', () => {
|
|
|
143
148
|
expect.any(Transaction),
|
|
144
149
|
expect.any(TransactionJournal),
|
|
145
150
|
expect.any(TransactionJournal),
|
|
146
|
-
expect.any(RecurringPayment),
|
|
147
151
|
expect.any(Contact),
|
|
148
152
|
expect.any(Permission),
|
|
153
|
+
expect.any(RecurringPayment),
|
|
149
154
|
expect.any(RecurringPaymentInstruction),
|
|
150
155
|
expect.any(ConcessionProof)
|
|
151
156
|
]
|
|
@@ -369,6 +374,43 @@ describe('transaction service', () => {
|
|
|
369
374
|
expect(paymentJournal.total).toBe(cost)
|
|
370
375
|
})
|
|
371
376
|
})
|
|
377
|
+
|
|
378
|
+
describe('recurring payment processing', () => {
|
|
379
|
+
it('passes transaction record to generateRecurringPaymentRecord', async () => {
|
|
380
|
+
const callingArgs = {}
|
|
381
|
+
generateRecurringPaymentRecord.mockImplementationOnce(transaction => {
|
|
382
|
+
callingArgs.transaction = JSON.parse(JSON.stringify(transaction))
|
|
383
|
+
})
|
|
384
|
+
const mockRecord = mockFinalisedTransactionRecord()
|
|
385
|
+
AwsMock.DynamoDB.DocumentClient.__setResponse('get', { Item: mockRecord })
|
|
386
|
+
await processQueue({ id: mockRecord.id })
|
|
387
|
+
// jest.fn args aren't immutable and transaction is changed in processQueue, so we use our clone that hasn't changed
|
|
388
|
+
expect(callingArgs.transaction).toEqual(mockRecord)
|
|
389
|
+
})
|
|
390
|
+
|
|
391
|
+
it('passes permission to generateRecurringPaymentRecord', async () => {
|
|
392
|
+
const mockRecord = mockFinalisedTransactionRecord()
|
|
393
|
+
const expectedPermissionData = {}
|
|
394
|
+
const keysToCopy = ['referenceNumber', 'issueDate', 'startDate', 'endDate', 'isRenewal']
|
|
395
|
+
for (const key of keysToCopy) {
|
|
396
|
+
expectedPermissionData[key] = mockRecord.permissions[0][key]
|
|
397
|
+
}
|
|
398
|
+
AwsMock.DynamoDB.DocumentClient.__setResponse('get', { Item: mockRecord })
|
|
399
|
+
|
|
400
|
+
await processQueue({ id: mockRecord.id })
|
|
401
|
+
|
|
402
|
+
expect(generateRecurringPaymentRecord).toHaveBeenCalledWith(expect.any(Object), expect.objectContaining(expectedPermissionData))
|
|
403
|
+
})
|
|
404
|
+
|
|
405
|
+
it('passes return value of generateRecurringPaymentRecord to processRecurringPayment', async () => {
|
|
406
|
+
const rprSymbol = Symbol('rpr')
|
|
407
|
+
const finalisedTransaction = mockFinalisedTransactionRecord()
|
|
408
|
+
generateRecurringPaymentRecord.mockReturnValueOnce(rprSymbol)
|
|
409
|
+
AwsMock.DynamoDB.DocumentClient.__setResponse('get', { Item: finalisedTransaction })
|
|
410
|
+
await processQueue({ id: finalisedTransaction.id })
|
|
411
|
+
expect(processRecurringPayment).toHaveBeenCalledWith(rprSymbol, expect.any(Contact))
|
|
412
|
+
})
|
|
413
|
+
})
|
|
372
414
|
})
|
|
373
415
|
|
|
374
416
|
describe('.getTransactionJournalRefNumber', () => {
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
} from '@defra-fish/dynamics-lib'
|
|
13
13
|
import { DDE_DATA_SOURCE, FULFILMENT_SWITCHOVER_DATE, POCL_TRANSACTION_SOURCES } from '@defra-fish/business-rules-lib'
|
|
14
14
|
import { getReferenceDataForEntityAndId, getGlobalOptionSetValue, getReferenceDataForEntity } from '../reference-data.service.js'
|
|
15
|
-
import { processRecurringPayment } from '../recurring-payments.service.js'
|
|
15
|
+
import { generateRecurringPaymentRecord, processRecurringPayment } from '../recurring-payments.service.js'
|
|
16
16
|
import { resolveContactPayload } from '../contacts.service.js'
|
|
17
17
|
import { retrieveStagedTransaction } from './retrieve-transaction.js'
|
|
18
18
|
import { TRANSACTION_STAGING_TABLE, TRANSACTION_STAGING_HISTORY_TABLE } from '../../config.js'
|
|
@@ -65,11 +65,6 @@ export async function processQueue ({ id }) {
|
|
|
65
65
|
isRenewal
|
|
66
66
|
)
|
|
67
67
|
|
|
68
|
-
const { recurringPayment } = await processRecurringPayment(transactionRecord, contact)
|
|
69
|
-
if (recurringPayment) {
|
|
70
|
-
entities.push(recurringPayment)
|
|
71
|
-
}
|
|
72
|
-
|
|
73
68
|
permission.bindToEntity(Permission.definition.relationships.licensee, contact)
|
|
74
69
|
permission.bindToEntity(Permission.definition.relationships.permit, permit)
|
|
75
70
|
permission.bindToEntity(Permission.definition.relationships.transaction, transaction)
|
|
@@ -78,7 +73,10 @@ export async function processQueue ({ id }) {
|
|
|
78
73
|
|
|
79
74
|
entities.push(contact, permission)
|
|
80
75
|
|
|
76
|
+
const { recurringPayment } = await processRecurringPayment(generateRecurringPaymentRecord(transactionRecord, permission), contact)
|
|
77
|
+
|
|
81
78
|
if (recurringPayment && permit.isRecurringPaymentSupported) {
|
|
79
|
+
entities.push(recurringPayment)
|
|
82
80
|
const paymentInstruction = new RecurringPaymentInstruction()
|
|
83
81
|
paymentInstruction.bindToEntity(RecurringPaymentInstruction.definition.relationships.licensee, contact)
|
|
84
82
|
paymentInstruction.bindToEntity(RecurringPaymentInstruction.definition.relationships.permit, permit)
|