@defra-fish/dynamics-lib 1.68.0-rc.4 → 1.68.0-rc.5
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 +2 -2
- package/src/entities/__tests__/rcr-activity.entity.spec.js +42 -0
- package/src/entities/rcr-activity.entity.js +95 -0
- package/src/index.js +2 -0
- package/src/queries/__tests__/contact.queries.spec.js +10 -21
- package/src/queries/__tests__/rcr-activity.queries.spec.js +48 -0
- package/src/queries/contact.queries.js +11 -12
- package/src/queries/rcr-activity.queries.js +27 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@defra-fish/dynamics-lib",
|
|
3
|
-
"version": "1.68.0-rc.
|
|
3
|
+
"version": "1.68.0-rc.5",
|
|
4
4
|
"description": "Framework to support integration with dynamics",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -43,5 +43,5 @@
|
|
|
43
43
|
"simple-oauth2": "4.3.0",
|
|
44
44
|
"uuid": "8.3.2"
|
|
45
45
|
},
|
|
46
|
-
"gitHead": "
|
|
46
|
+
"gitHead": "eb79690f23e81424ffc7f2fef88a193d0bd6d27f"
|
|
47
47
|
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { Contact, RCRActivity, RCR_ACTIVITY_STATUS } from '../../index.js'
|
|
2
|
+
|
|
3
|
+
describe('rcr activity entity', () => {
|
|
4
|
+
it('maps from dynamics', async () => {
|
|
5
|
+
const rcrActivity = RCRActivity.fromResponse({
|
|
6
|
+
activityid: '1',
|
|
7
|
+
defra_activitystatus: RCR_ACTIVITY_STATUS.STARTED,
|
|
8
|
+
defra_season: 2025,
|
|
9
|
+
actualstart: '2020-03-31T22:59:00Z',
|
|
10
|
+
modifiedon: '2020-03-31T22:59:00Z',
|
|
11
|
+
actualend: '2020-03-31T22:59:00Z'
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
expect(rcrActivity.id).toBe('1')
|
|
15
|
+
expect(rcrActivity.status).toBe(RCR_ACTIVITY_STATUS.STARTED)
|
|
16
|
+
expect(rcrActivity.season).toBe(2025)
|
|
17
|
+
expect(rcrActivity.startDate).toBe('2020-03-31T22:59:00Z')
|
|
18
|
+
expect(rcrActivity.lastUpdated).toBe('2020-03-31T22:59:00Z')
|
|
19
|
+
expect(rcrActivity.submittedDate).toBe('2020-03-31T22:59:00Z')
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
it('maps to dynamics', async () => {
|
|
23
|
+
const rcrActivity = new RCRActivity()
|
|
24
|
+
rcrActivity.status = RCR_ACTIVITY_STATUS.SUBMITTED
|
|
25
|
+
rcrActivity.season = 2025
|
|
26
|
+
rcrActivity.startDate = '2020-03-31T22:59:00Z'
|
|
27
|
+
rcrActivity.submittedDate = '2020-03-31T22:59:00Z'
|
|
28
|
+
|
|
29
|
+
const contact = new Contact()
|
|
30
|
+
rcrActivity.bindToEntity(RCRActivity.definition.relationships.licensee, contact)
|
|
31
|
+
|
|
32
|
+
const expectedFields = {
|
|
33
|
+
actualend: '2020-03-31T22:59:00Z',
|
|
34
|
+
actualstart: '2020-03-31T22:59:00Z',
|
|
35
|
+
defra_activitystatus: RCR_ACTIVITY_STATUS.SUBMITTED,
|
|
36
|
+
defra_season: 2025,
|
|
37
|
+
'regardingobjectid_contact_defra_rcractivity@odata.bind': `$${contact.uniqueContentId}`
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
expect(rcrActivity.toRequestBody()).toStrictEqual(expectedFields)
|
|
41
|
+
})
|
|
42
|
+
})
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { BaseEntity, EntityDefinition } from './base.entity.js'
|
|
2
|
+
import { Contact } from './contact.entity.js'
|
|
3
|
+
|
|
4
|
+
export const RCR_ACTIVITY_STATUS = Object.freeze({
|
|
5
|
+
STARTED: 910400000,
|
|
6
|
+
SUBMITTED: 910400001
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* RCRActivity entity
|
|
11
|
+
* @extends BaseEntity
|
|
12
|
+
*/
|
|
13
|
+
export class RCRActivity extends BaseEntity {
|
|
14
|
+
/** @type {EntityDefinition} */
|
|
15
|
+
static _definition = new EntityDefinition(() => ({
|
|
16
|
+
localName: 'rcrActivity',
|
|
17
|
+
dynamicsCollection: 'defra_rcractivities',
|
|
18
|
+
defaultFilter: 'statecode eq 0',
|
|
19
|
+
mappings: {
|
|
20
|
+
id: { field: 'activityid', type: 'string' },
|
|
21
|
+
status: { field: 'defra_activitystatus', type: 'integer' },
|
|
22
|
+
season: { field: 'defra_season', type: 'integer' },
|
|
23
|
+
startDate: { field: 'actualstart', type: 'datetime' },
|
|
24
|
+
lastUpdated: { field: 'modifiedon', type: 'datetime' },
|
|
25
|
+
submittedDate: { field: 'actualend', type: 'datetime' }
|
|
26
|
+
},
|
|
27
|
+
relationships: {
|
|
28
|
+
licensee: { property: 'regardingobjectid_contact_defra_rcractivity', entity: Contact, parent: true }
|
|
29
|
+
}
|
|
30
|
+
}))
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* The {@link EntityDefinition} providing mappings between Dynamics entity and the local entity
|
|
34
|
+
* @type {EntityDefinition}
|
|
35
|
+
*/
|
|
36
|
+
static get definition () {
|
|
37
|
+
return RCRActivity._definition
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* The status associated with the rcr activity
|
|
42
|
+
* @type {RCR_ACTIVITY_STATUS}
|
|
43
|
+
*/
|
|
44
|
+
get status () {
|
|
45
|
+
return super._getState('status')
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
set status (status) {
|
|
49
|
+
super._setState('status', status)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* The season associated with the rcr activity
|
|
54
|
+
* @type {number}
|
|
55
|
+
*/
|
|
56
|
+
get season () {
|
|
57
|
+
return super._getState('season')
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
set season (season) {
|
|
61
|
+
super._setState('season', season)
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
/**
|
|
65
|
+
* The start date associated with the rcr activity
|
|
66
|
+
* @type {date}
|
|
67
|
+
*/
|
|
68
|
+
get startDate () {
|
|
69
|
+
return super._getState('startDate')
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
set startDate (startDate) {
|
|
73
|
+
super._setState('startDate', startDate)
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* The last updated date associated with the rcr activity
|
|
78
|
+
* @type {date}
|
|
79
|
+
*/
|
|
80
|
+
get lastUpdated () {
|
|
81
|
+
return super._getState('lastUpdated')
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* The submitted date associated with the rcr activity
|
|
86
|
+
* @type {date}
|
|
87
|
+
*/
|
|
88
|
+
get submittedDate () {
|
|
89
|
+
return super._getState('submittedDate')
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
set submittedDate (submittedDate) {
|
|
93
|
+
super._setState('submittedDate', submittedDate)
|
|
94
|
+
}
|
|
95
|
+
}
|
package/src/index.js
CHANGED
|
@@ -13,6 +13,7 @@ export * from './entities/transaction-currency.entity.js'
|
|
|
13
13
|
export * from './entities/pocl-file.entity.js'
|
|
14
14
|
export * from './entities/pocl-staging-exception.entity.js'
|
|
15
15
|
export * from './entities/pocl-validation-error.entity.js'
|
|
16
|
+
export * from './entities/rcr-activity.entity.js'
|
|
16
17
|
export * from './entities/recurring-payment.entity.js'
|
|
17
18
|
export * from './entities/recurring-payment-instruction.entity.js'
|
|
18
19
|
export * from './entities/staging-exception.entity.js'
|
|
@@ -29,6 +30,7 @@ export * from './queries/pocl-validation-error.queries.js'
|
|
|
29
30
|
export * from './queries/recurring-payments.queries.js'
|
|
30
31
|
export * from './queries/contact.queries.js'
|
|
31
32
|
export * from './queries/activity.queries.js'
|
|
33
|
+
export * from './queries/rcr-activity.queries.js'
|
|
32
34
|
|
|
33
35
|
// Framework functionality
|
|
34
36
|
export * from './client/util.js'
|
|
@@ -63,19 +63,8 @@ describe('Contact Queries', () => {
|
|
|
63
63
|
jest.resetAllMocks()
|
|
64
64
|
|
|
65
65
|
jest.spyOn(Contact.definition, 'mappings', 'get').mockReturnValue({
|
|
66
|
-
id: { field: '
|
|
67
|
-
postcode: { field: '
|
|
68
|
-
})
|
|
69
|
-
|
|
70
|
-
jest.spyOn(Permission.definition, 'mappings', 'get').mockReturnValue({
|
|
71
|
-
referenceNumber: { field: 'mock_reference' },
|
|
72
|
-
issueDate: { field: 'mock_issueDate' }
|
|
73
|
-
})
|
|
74
|
-
|
|
75
|
-
jest.spyOn(Permission.definition, 'defaultFilter', 'get').mockReturnValue('statecode eq 0')
|
|
76
|
-
|
|
77
|
-
jest.spyOn(Permission.definition, 'relationships', 'get').mockReturnValue({
|
|
78
|
-
licensee: { property: 'mock_licensee' }
|
|
66
|
+
id: { field: 'contactid' },
|
|
67
|
+
postcode: { field: 'defra_postcode' }
|
|
79
68
|
})
|
|
80
69
|
})
|
|
81
70
|
|
|
@@ -93,14 +82,14 @@ describe('Contact Queries', () => {
|
|
|
93
82
|
const result = contactAndPermissionForLicensee('ABC123', 'AB12 3CD')
|
|
94
83
|
|
|
95
84
|
expect(result._retrieveRequest.filter).toEqual(
|
|
96
|
-
"endswith(
|
|
85
|
+
"endswith(defra_name, 'ABC123') and statecode eq 0 and defra_ContactId/defra_postcode eq 'AB12 3CD'"
|
|
97
86
|
)
|
|
98
87
|
})
|
|
99
88
|
|
|
100
89
|
it('should build correct orderBy', () => {
|
|
101
90
|
const result = contactAndPermissionForLicensee('ABC123', 'AB12 3CD')
|
|
102
91
|
|
|
103
|
-
expect(result._retrieveRequest.orderBy).toEqual(['
|
|
92
|
+
expect(result._retrieveRequest.orderBy).toEqual(['defra_issuedate desc', 'defra_ContactId/contactid asc'])
|
|
104
93
|
})
|
|
105
94
|
|
|
106
95
|
it('should set expand correctly', () => {
|
|
@@ -108,8 +97,8 @@ describe('Contact Queries', () => {
|
|
|
108
97
|
|
|
109
98
|
expect(result._retrieveRequest.expand).toEqual([
|
|
110
99
|
{
|
|
111
|
-
property: '
|
|
112
|
-
select: ['
|
|
100
|
+
property: 'defra_ContactId',
|
|
101
|
+
select: ['contactid', 'defra_postcode']
|
|
113
102
|
}
|
|
114
103
|
])
|
|
115
104
|
})
|
|
@@ -125,12 +114,12 @@ describe('Contact Queries', () => {
|
|
|
125
114
|
|
|
126
115
|
expect(result._retrieveRequest).toEqual({
|
|
127
116
|
collection: 'defra_permissions',
|
|
128
|
-
filter: `endswith(
|
|
129
|
-
orderBy: ['
|
|
117
|
+
filter: `endswith(defra_name, '${permissionLast6}') and statecode eq 0 and defra_ContactId/defra_postcode eq '${postcode}'`,
|
|
118
|
+
orderBy: ['defra_issuedate desc', 'defra_ContactId/contactid asc'],
|
|
130
119
|
expand: [
|
|
131
120
|
{
|
|
132
|
-
property: '
|
|
133
|
-
select: ['
|
|
121
|
+
property: 'defra_ContactId',
|
|
122
|
+
select: ['contactid', 'defra_postcode']
|
|
134
123
|
}
|
|
135
124
|
],
|
|
136
125
|
select: [
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { RCRActivity } from '../../entities/rcr-activity.entity.js'
|
|
2
|
+
import { PredefinedQuery } from '../predefined-query.js'
|
|
3
|
+
import { rcrActivityForContact } from '../rcr-activity.queries.js'
|
|
4
|
+
|
|
5
|
+
describe('rcrActivityForContact', () => {
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
jest.resetAllMocks()
|
|
8
|
+
})
|
|
9
|
+
|
|
10
|
+
it('should return a predefined query', () => {
|
|
11
|
+
const result = rcrActivityForContact('CONTACT123', 2024)
|
|
12
|
+
expect(result).toBeInstanceOf(PredefinedQuery)
|
|
13
|
+
})
|
|
14
|
+
|
|
15
|
+
it('root should return RCRActivity', () => {
|
|
16
|
+
const result = rcrActivityForContact('CONTACT123', 2024)
|
|
17
|
+
expect(result._root).toEqual(RCRActivity)
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
it('should build correct filter', () => {
|
|
21
|
+
const result = rcrActivityForContact('CONTACT123', 2024)
|
|
22
|
+
|
|
23
|
+
expect(result._retrieveRequest.filter).toEqual(
|
|
24
|
+
"regardingobjectid_contact_defra_rcractivity/contactid eq 'CONTACT123' and defra_season eq 2024 and statecode eq 0"
|
|
25
|
+
)
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it('should set expand to empty array', () => {
|
|
29
|
+
const result = rcrActivityForContact('CONTACT123', 2024)
|
|
30
|
+
|
|
31
|
+
expect(result._retrieveRequest.expand).toEqual([])
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
it.each([
|
|
35
|
+
['ABC123', 2023],
|
|
36
|
+
['XYZ999', 2024],
|
|
37
|
+
['AAAAAA', 2025]
|
|
38
|
+
])('should return correct retrieve request when contactId is %s and season is %s', (contactId, season) => {
|
|
39
|
+
const result = rcrActivityForContact(contactId, season)
|
|
40
|
+
|
|
41
|
+
expect(result._retrieveRequest).toEqual({
|
|
42
|
+
collection: 'defra_rcractivities',
|
|
43
|
+
filter: `regardingobjectid_contact_defra_rcractivity/contactid eq '${contactId}' and defra_season eq ${season} and statecode eq 0`,
|
|
44
|
+
expand: [],
|
|
45
|
+
select: ['activityid', 'defra_activitystatus', 'defra_season', 'actualstart', 'modifiedon', 'actualend']
|
|
46
|
+
})
|
|
47
|
+
})
|
|
48
|
+
})
|
|
@@ -18,21 +18,20 @@ export const contactForLicenseeNoReference = (licenseeBirthDate, licenseePostcod
|
|
|
18
18
|
/**
|
|
19
19
|
* Gets the query to get a contact by the last 6 characters if their license number and postcode
|
|
20
20
|
*
|
|
21
|
-
* @param permissionLast6Characters the last 6 characters of the permission reference number
|
|
22
|
-
* @param licenseePostcode the postcode of the contact associated with the permission
|
|
23
|
-
* @returns {
|
|
21
|
+
* @param {string} permissionLast6Characters the last 6 characters of the permission reference number
|
|
22
|
+
* @param {string} licenseePostcode the postcode of the contact associated with the permission
|
|
23
|
+
* @returns {PredefinedQuery<Permission>} returns a query as an object to fetch the contact
|
|
24
24
|
*/
|
|
25
25
|
|
|
26
26
|
export const contactAndPermissionForLicensee = (permissionLast6Characters, licenseePostcode) => {
|
|
27
|
-
const
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
]
|
|
27
|
+
const { referenceNumber, issueDate } = Permission.definition.mappings
|
|
28
|
+
const { licensee } = Permission.definition.relationships
|
|
29
|
+
const { id } = Contact.definition.mappings
|
|
30
|
+
|
|
31
|
+
const filter = `endswith(${referenceNumber.field}, '${escapeODataStringValue(permissionLast6Characters)}') and ${
|
|
32
|
+
Permission.definition.defaultFilter
|
|
33
|
+
} and ${licensee.property}/${Contact.definition.mappings.postcode.field} eq '${escapeODataStringValue(licenseePostcode)}'`
|
|
34
|
+
const orderBy = [`${issueDate.field} desc`, `${licensee.property}/${id.field} asc`]
|
|
36
35
|
|
|
37
36
|
const query = new PredefinedQuery({
|
|
38
37
|
root: Permission,
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { Contact } from '../entities/contact.entity.js'
|
|
2
|
+
import { RCRActivity } from '../entities/rcr-activity.entity.js'
|
|
3
|
+
import { escapeODataStringValue } from '../client/util.js'
|
|
4
|
+
import { PredefinedQuery } from './predefined-query.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Creates a predefined OData query for retrieving {@link RCRActivity} records
|
|
8
|
+
* associated with a specific contact id and season.
|
|
9
|
+
*
|
|
10
|
+
* @param {string} contactId The unique identifier of the {@link Contact}.
|
|
11
|
+
* @param {string|number} seasonInput The season value to filter activities by.
|
|
12
|
+
* @returns {PredefinedQuery<RCRActivity>} returns a query as an object to fetch the contact
|
|
13
|
+
*/
|
|
14
|
+
export const rcrActivityForContact = (contactId, seasonInput) => {
|
|
15
|
+
const { season } = RCRActivity.definition.mappings
|
|
16
|
+
const { licensee } = RCRActivity.definition.relationships
|
|
17
|
+
const { id } = Contact.definition.mappings
|
|
18
|
+
|
|
19
|
+
const filter = `${licensee.property}/${id.field} eq '${escapeODataStringValue(contactId)}' and ${
|
|
20
|
+
season.field
|
|
21
|
+
} eq ${escapeODataStringValue(seasonInput)} and ${RCRActivity.definition.defaultFilter}`
|
|
22
|
+
return new PredefinedQuery({
|
|
23
|
+
root: RCRActivity,
|
|
24
|
+
filter,
|
|
25
|
+
expand: []
|
|
26
|
+
})
|
|
27
|
+
}
|