@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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defra-fish/dynamics-lib",
3
- "version": "1.68.0-rc.4",
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": "bc5bd6cb2ae39fbae443435ac1f71bb7beb85b43"
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: 'mock_contactid' },
67
- postcode: { field: 'mock_postcode' }
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(mock_reference, 'ABC123') and statecode eq 0 and mock_licensee/mock_postcode eq 'AB12 3CD'"
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(['mock_issueDate desc', 'mock_licensee/mock_contactid asc'])
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: 'mock_licensee',
112
- select: ['mock_contactid', 'mock_postcode']
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(mock_reference, '${permissionLast6}') and statecode eq 0 and mock_licensee/mock_postcode eq '${postcode}'`,
129
- orderBy: ['mock_issueDate desc', 'mock_licensee/mock_contactid asc'],
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: 'mock_licensee',
133
- select: ['mock_contactid', 'mock_postcode']
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 {Object} returns a query as an object to fetch the contact
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 filter = `endswith(${Permission.definition.mappings.referenceNumber.field}, '${escapeODataStringValue(
28
- permissionLast6Characters
29
- )}') and ${Permission.definition.defaultFilter} and ${Permission.definition.relationships.licensee.property}/${
30
- Contact.definition.mappings.postcode.field
31
- } eq '${escapeODataStringValue(licenseePostcode)}'`
32
- const orderBy = [
33
- `${Permission.definition.mappings.issueDate.field} desc`,
34
- `${Permission.definition.relationships.licensee.property}/${Contact.definition.mappings.id.field} asc`
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
+ }