@defra-fish/dynamics-lib 1.44.0-rc.1 → 1.44.0-rc.3

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.44.0-rc.1",
3
+ "version": "1.44.0-rc.3",
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": "4d3a16e5eac763b13e68f0af2c295a1f0ad12e78"
46
+ "gitHead": "4a8c0f801a97958a7b6e92cc0d9f0f87b5d05c8a"
47
47
  }
@@ -6630,6 +6630,57 @@
6630
6630
  }
6631
6631
  ]
6632
6632
  },
6633
+ {
6634
+ "Name": "defra_cancelledreason",
6635
+ "MetadataId": "c5bb4ec0-78b5-4413-9c95-b879793343c7",
6636
+ "Options": [
6637
+ {
6638
+ "Value": 910400195,
6639
+ "Color": "#0000ff",
6640
+ "IsManaged": false,
6641
+ "ExternalValue": null,
6642
+ "ParentValues": [],
6643
+ "MetadataId": null,
6644
+ "HasChanged": null,
6645
+ "Label": {
6646
+ "LocalizedLabels": [
6647
+ {
6648
+ "Label": "User cancelled",
6649
+ "LanguageCode": 1033,
6650
+ "IsManaged": false,
6651
+ "MetadataId": "cd2cfff1-d4e1-e711-810c-5065f38ada61",
6652
+ "HasChanged": null
6653
+ }
6654
+ ],
6655
+ "UserLocalizedLabel": {
6656
+ "Label": "User cancelled",
6657
+ "LanguageCode": 1033,
6658
+ "IsManaged": false,
6659
+ "MetadataId": "cd2cfff1-d4e1-e711-810c-5065f38ada61",
6660
+ "HasChanged": null
6661
+ }
6662
+ },
6663
+ "Description": {
6664
+ "LocalizedLabels": [
6665
+ {
6666
+ "Label": "",
6667
+ "LanguageCode": 1033,
6668
+ "IsManaged": false,
6669
+ "MetadataId": "de2cfff1-d4e1-e711-810c-5065f38ada61",
6670
+ "HasChanged": null
6671
+ }
6672
+ ],
6673
+ "UserLocalizedLabel": {
6674
+ "Label": "",
6675
+ "LanguageCode": 1033,
6676
+ "IsManaged": false,
6677
+ "MetadataId": "de2cfff1-d4e1-e711-810c-5065f38ada61",
6678
+ "HasChanged": null
6679
+ }
6680
+ }
6681
+ }
6682
+ ]
6683
+ },
6633
6684
  {
6634
6685
  "Name": "defra_poclfilestatus",
6635
6686
  "MetadataId": "ed91518d-2948-4b5b-8cc2-cb9ce7cb751c",
@@ -1,4 +1,4 @@
1
- import { Contact, RecurringPayment, retrieveGlobalOptionSets } from '../../index.js'
1
+ import { Contact, Permission, RecurringPayment, retrieveGlobalOptionSets } from '../../index.js'
2
2
 
3
3
  let optionSetData
4
4
  describe('recurring payment entity', () => {
@@ -6,52 +6,149 @@ describe('recurring payment entity', () => {
6
6
  optionSetData = await retrieveGlobalOptionSets().cached()
7
7
  })
8
8
 
9
- it('maps from dynamics', async () => {
10
- const recurringPayment = RecurringPayment.fromResponse(
11
- {
12
- '@odata.etag': 'W/"53585133"',
13
- defra_recurringpaymentid: 'b5b24adf-2e83-ea11-a811-000d3a649213',
14
- defra_name: '18569ba8-094e-4e8c-9911-bfedd5ccc17a',
15
- defra_mandate: 'c9267c6e-573d-488b-99ab-ea18431fc472',
16
- defra_inceptionday: 2,
17
- defra_inceptionmonth: 1
18
- },
19
- optionSetData
20
- )
21
-
22
- const expectedFields = {
23
- id: 'b5b24adf-2e83-ea11-a811-000d3a649213',
24
- referenceNumber: '18569ba8-094e-4e8c-9911-bfedd5ccc17a',
25
- mandate: 'c9267c6e-573d-488b-99ab-ea18431fc472',
26
- inceptionDay: 2,
27
- inceptionMonth: 1
9
+ const createRecurringPayment = (contact, permission, cancelledDate, cancelledReason) => {
10
+ const recurringPayment = new RecurringPayment()
11
+
12
+ recurringPayment.name = 'Test Name'
13
+ recurringPayment.nextDueDate = '2019-12-14T00:00:00Z'
14
+ recurringPayment.cancelledDate = cancelledDate
15
+ recurringPayment.cancelledReason = cancelledReason
16
+ recurringPayment.endDate = '2019-12-15T00:00:00Z'
17
+ recurringPayment.agreementId = 'c9267c6e-573d-488b-99ab-ea18431fc472'
18
+ recurringPayment.publicId = '649-213'
19
+ recurringPayment.status = 1
20
+ recurringPayment.contactId = 'b3d33cln-2e83-ea11-a811-000d3a649213'
21
+ recurringPayment.activePermission = 'a5b24adf-2e83-ea11-a811-000d3a649213'
22
+
23
+ recurringPayment.bindToEntity(RecurringPayment.definition.relationships.contact, contact)
24
+ recurringPayment.bindToEntity(RecurringPayment.definition.relationships.activePermission, permission)
25
+
26
+ return recurringPayment
27
+ }
28
+
29
+ const getRecurringPayment = (overrides = {}) => {
30
+ const defaultResponse = {
31
+ '@odata.etag': 'W/"11528905"',
32
+ defra_recurringpaymentid: 'b5b24adf-2e83-ea11-a811-000d3a649213',
33
+ defra_name: '18569ba8-094e-4e8c-9911-bfedd5ccc17a',
34
+ defra_nextduedate: '2019-12-14T00:00:00Z',
35
+ defra_cancelleddate: '2019-12-14T00:00:00Z',
36
+ defra_cancelledreason: 910400195,
37
+ defra_enddate: '2019-12-15T00:00:00Z',
38
+ defra_agreementid: 'c9267c6e-573d-488b-99ab-ea18431fc472',
39
+ defra_publicid: '649-213',
40
+ statecode: 1,
41
+ _defra_contact_value: 'b3d33cln-2e83-ea11-a811-000d3a649213',
42
+ _defra_activepermission_value: 'a5b24adf-2e83-ea11-a811-000d3a649213'
28
43
  }
29
44
 
30
- expect(recurringPayment).toBeInstanceOf(RecurringPayment)
31
- expect(recurringPayment).toMatchObject(expect.objectContaining({ etag: 'W/"53585133"', ...expectedFields }))
32
- expect(recurringPayment.toJSON()).toMatchObject(expect.objectContaining(expectedFields))
33
- expect(JSON.parse(recurringPayment.toString())).toMatchObject(expect.objectContaining(expectedFields))
45
+ const response = { ...defaultResponse, ...overrides }
46
+
47
+ return RecurringPayment.fromResponse(response, optionSetData)
48
+ }
49
+
50
+ describe('mappings with cancelled rp', () => {
51
+ it('is a recurring payment', () => {
52
+ const recurringPayment = getRecurringPayment()
53
+ expect(recurringPayment).toBeInstanceOf(RecurringPayment)
54
+ })
55
+
56
+ it('matches expectedFields', () => {
57
+ const recurringPayment = getRecurringPayment()
58
+ expect(recurringPayment).toMatchObject(
59
+ expect.objectContaining({
60
+ etag: 'W/"11528905"',
61
+ id: 'b5b24adf-2e83-ea11-a811-000d3a649213',
62
+ name: '18569ba8-094e-4e8c-9911-bfedd5ccc17a',
63
+ nextDueDate: '2019-12-14T00:00:00Z',
64
+ cancelledDate: '2019-12-14T00:00:00Z',
65
+ cancelledReason: expect.objectContaining({ id: 910400195, label: 'User cancelled', description: 'User cancelled' }),
66
+ endDate: '2019-12-15T00:00:00Z',
67
+ agreementId: 'c9267c6e-573d-488b-99ab-ea18431fc472',
68
+ publicId: '649-213',
69
+ status: 1,
70
+ activePermission: 'a5b24adf-2e83-ea11-a811-000d3a649213',
71
+ contactId: 'b3d33cln-2e83-ea11-a811-000d3a649213'
72
+ })
73
+ )
74
+ })
75
+
76
+ it('maps to dynamics', async () => {
77
+ const contact = new Contact()
78
+ const permission = new Permission()
79
+ const recurringPayment = createRecurringPayment(
80
+ contact,
81
+ permission,
82
+ '2019-10-14T00:00:00Z',
83
+ optionSetData.defra_cancelledreason.options['910400195']
84
+ )
85
+ const dynamicsEntity = recurringPayment.toRequestBody()
86
+ expect(dynamicsEntity).toMatchObject(
87
+ expect.objectContaining({
88
+ defra_name: 'Test Name',
89
+ defra_nextduedate: '2019-12-14T00:00:00Z',
90
+ defra_cancelleddate: '2019-10-14T00:00:00Z',
91
+ defra_cancelledreason: 910400195,
92
+ defra_enddate: '2019-12-15T00:00:00Z',
93
+ defra_agreementid: 'c9267c6e-573d-488b-99ab-ea18431fc472',
94
+ defra_publicid: '649-213',
95
+ statecode: 1,
96
+ _defra_activepermission_value: 'a5b24adf-2e83-ea11-a811-000d3a649213',
97
+ _defra_contact_value: 'b3d33cln-2e83-ea11-a811-000d3a649213',
98
+ 'defra_Contact@odata.bind': `$${contact.uniqueContentId}`,
99
+ 'defra_ActivePermission@odata.bind': `$${permission.uniqueContentId}`
100
+ })
101
+ )
102
+ })
34
103
  })
35
104
 
36
- it('maps to dynamics', async () => {
37
- const contact = new Contact()
105
+ describe('mappings without cancelled rp', () => {
106
+ it('is a recurring payment', () => {
107
+ const recurringPayment = getRecurringPayment({ defra_cancelleddate: null, defra_cancelledreason: null })
108
+ expect(recurringPayment).toBeInstanceOf(RecurringPayment)
109
+ })
38
110
 
39
- const recurringPayment = new RecurringPayment()
40
- recurringPayment.referenceNumber = 'Test Reference Number'
41
- recurringPayment.mandate = 'Test mandate'
42
- recurringPayment.inceptionDay = 28
43
- recurringPayment.inceptionMonth = 2
44
- recurringPayment.bindToEntity(RecurringPayment.definition.relationships.payer, contact)
45
-
46
- const dynamicsEntity = recurringPayment.toRequestBody()
47
- expect(dynamicsEntity).toMatchObject(
48
- expect.objectContaining({
49
- defra_name: 'Test Reference Number',
50
- defra_mandate: 'Test mandate',
51
- defra_inceptionday: 28,
52
- defra_inceptionmonth: 2,
53
- 'defra_Contact@odata.bind': `$${contact.uniqueContentId}`
54
- })
55
- )
111
+ it('matches expectedFields', () => {
112
+ const recurringPayment = getRecurringPayment({ defra_cancelleddate: null, defra_cancelledreason: null })
113
+ expect(recurringPayment).toMatchObject(
114
+ expect.objectContaining({
115
+ etag: 'W/"11528905"',
116
+ id: 'b5b24adf-2e83-ea11-a811-000d3a649213',
117
+ name: '18569ba8-094e-4e8c-9911-bfedd5ccc17a',
118
+ nextDueDate: '2019-12-14T00:00:00Z',
119
+ cancelledDate: null,
120
+ cancelledReason: null,
121
+ endDate: '2019-12-15T00:00:00Z',
122
+ agreementId: 'c9267c6e-573d-488b-99ab-ea18431fc472',
123
+ publicId: '649-213',
124
+ status: 1,
125
+ activePermission: 'a5b24adf-2e83-ea11-a811-000d3a649213',
126
+ contactId: 'b3d33cln-2e83-ea11-a811-000d3a649213'
127
+ })
128
+ )
129
+ })
130
+
131
+ it('maps to dynamics', async () => {
132
+ const contact = new Contact()
133
+ const permission = new Permission()
134
+ const recurringPayment = createRecurringPayment(contact, permission, null, null)
135
+ const dynamicsEntity = recurringPayment.toRequestBody()
136
+ expect(dynamicsEntity).toMatchObject(
137
+ expect.objectContaining({
138
+ defra_name: 'Test Name',
139
+ defra_nextduedate: '2019-12-14T00:00:00Z',
140
+ defra_cancelleddate: null,
141
+ defra_cancelledreason: null,
142
+ defra_enddate: '2019-12-15T00:00:00Z',
143
+ defra_agreementid: 'c9267c6e-573d-488b-99ab-ea18431fc472',
144
+ defra_publicid: '649-213',
145
+ statecode: 1,
146
+ _defra_activepermission_value: 'a5b24adf-2e83-ea11-a811-000d3a649213',
147
+ _defra_contact_value: 'b3d33cln-2e83-ea11-a811-000d3a649213',
148
+ 'defra_Contact@odata.bind': `$${contact.uniqueContentId}`,
149
+ 'defra_ActivePermission@odata.bind': `$${permission.uniqueContentId}`
150
+ })
151
+ )
152
+ })
56
153
  })
57
154
  })
@@ -1,5 +1,6 @@
1
1
  import { BaseEntity, EntityDefinition } from './base.entity.js'
2
2
  import { Contact } from './contact.entity.js'
3
+ import { Permission } from './permission.entity.js'
3
4
 
4
5
  /**
5
6
  * Recurring payment entity
@@ -13,13 +14,20 @@ export class RecurringPayment extends BaseEntity {
13
14
  defaultFilter: 'statecode eq 0',
14
15
  mappings: {
15
16
  id: { field: 'defra_recurringpaymentid', type: 'string' },
16
- referenceNumber: { field: 'defra_name', type: 'string' },
17
- mandate: { field: 'defra_mandate', type: 'string' },
18
- inceptionDay: { field: 'defra_inceptionday', type: 'integer' },
19
- inceptionMonth: { field: 'defra_inceptionmonth', type: 'integer' }
17
+ name: { field: 'defra_name', type: 'string' },
18
+ status: { field: 'statecode', type: 'decimal' },
19
+ nextDueDate: { field: 'defra_nextduedate', type: 'datetime' },
20
+ cancelledDate: { field: 'defra_cancelleddate', type: 'datetime' },
21
+ cancelledReason: { field: 'defra_cancelledreason', type: 'optionset', ref: 'defra_cancelledreason' },
22
+ endDate: { field: 'defra_enddate', type: 'datetime' },
23
+ agreementId: { field: 'defra_agreementid', type: 'string' },
24
+ activePermission: { field: '_defra_activepermission_value', type: 'string' },
25
+ contactId: { field: '_defra_contact_value', type: 'string' },
26
+ publicId: { field: 'defra_publicid', type: 'string' }
20
27
  },
21
28
  relationships: {
22
- payer: { property: 'defra_Contact', entity: Contact, parent: true }
29
+ contact: { property: 'defra_Contact', entity: Contact, parent: true },
30
+ activePermission: { property: 'defra_ActivePermission', entity: Permission, parent: true }
23
31
  }
24
32
  }))
25
33
 
@@ -32,52 +40,122 @@ export class RecurringPayment extends BaseEntity {
32
40
  }
33
41
 
34
42
  /**
35
- * The reference number associated with the recurring payment
43
+ * The default name associated with the recurring payment
36
44
  * @type {string}
37
45
  */
38
- get referenceNumber () {
39
- return super._getState('referenceNumber')
46
+ get name () {
47
+ return super._getState('name')
40
48
  }
41
49
 
42
- set referenceNumber (referenceNumber) {
43
- super._setState('referenceNumber', referenceNumber)
50
+ set name (name) {
51
+ super._setState('name', name)
44
52
  }
45
53
 
46
54
  /**
47
- * The mandate identifier associated with the recurring payment
55
+ * The date the recurring payment is due
56
+ * @type {datetime}
57
+ */
58
+ get nextDueDate () {
59
+ return super._getState('nextDueDate')
60
+ }
61
+
62
+ set nextDueDate (nextDueDate) {
63
+ super._setState('nextDueDate', nextDueDate)
64
+ }
65
+
66
+ /**
67
+ * The date the recurring payment was cancelled
68
+ * @type {datetime}
69
+ */
70
+ get cancelledDate () {
71
+ return super._getState('cancelledDate')
72
+ }
73
+
74
+ set cancelledDate (cancelledDate) {
75
+ super._setState('cancelledDate', cancelledDate)
76
+ }
77
+
78
+ /**
79
+ * The reason the recurring payment was cancelled
80
+ * @type {GlobalOptionSetDefinition}
81
+ */
82
+ get cancelledReason () {
83
+ return super._getState('cancelledReason')
84
+ }
85
+
86
+ set cancelledReason (cancelledReason) {
87
+ super._setState('cancelledReason', cancelledReason)
88
+ }
89
+
90
+ /**
91
+ * The end of the recurring payment
92
+ * @type {datetime}
93
+ */
94
+ get endDate () {
95
+ return super._getState('endDate')
96
+ }
97
+
98
+ set endDate (endDate) {
99
+ super._setState('endDate', endDate)
100
+ }
101
+
102
+ /**
103
+ * The agreement identification number
48
104
  * @type {string}
49
105
  */
50
- get mandate () {
51
- return super._getState('mandate')
106
+ get agreementId () {
107
+ return super._getState('agreementId')
52
108
  }
53
109
 
54
- set mandate (mandate) {
55
- super._setState('mandate', mandate)
110
+ set agreementId (agreementId) {
111
+ super._setState('agreementId', agreementId)
56
112
  }
57
113
 
58
114
  /**
59
- * The inception day associated with the recurring payment
60
- * @type {integer}
115
+ * Hash of the id
116
+ * @type {string}
61
117
  */
62
- get inceptionDay () {
63
- return super._getState('inceptionDay')
118
+ get publicId () {
119
+ return super._getState('publicId')
64
120
  }
65
121
 
66
- set inceptionDay (inceptionDay) {
67
- super._setState('inceptionDay', inceptionDay)
122
+ set publicId (publicId) {
123
+ super._setState('publicId', publicId)
68
124
  }
69
125
 
70
126
  /**
71
- * The inception month associated with the recurring payment
72
- * Note: Months are zero indexed, so January is month 0.
73
- *
74
- * @type {integer}
127
+ * The state code
128
+ * @type {decimal}
129
+ */
130
+ get status () {
131
+ return super._getState('status')
132
+ }
133
+
134
+ set status (status) {
135
+ super._setState('status', status)
136
+ }
137
+
138
+ /**
139
+ * The ID of the associated contact
140
+ * @type {string}
141
+ */
142
+ get contactId () {
143
+ return super._getState('contactId')
144
+ }
145
+
146
+ set contactId (contactId) {
147
+ super._setState('contactId', contactId)
148
+ }
149
+
150
+ /**
151
+ * The ID of the associated active permission
152
+ * @type {string}
75
153
  */
76
- get inceptionMonth () {
77
- return super._getState('inceptionMonth')
154
+ get activePermission () {
155
+ return super._getState('activePermission')
78
156
  }
79
157
 
80
- set inceptionMonth (inceptionMonth) {
81
- super._setState('inceptionMonth', inceptionMonth)
158
+ set activePermission (activePermission) {
159
+ super._setState('activePermission', activePermission)
82
160
  }
83
161
  }
package/src/index.js CHANGED
@@ -26,6 +26,7 @@ export * from './queries/permission.queries.js'
26
26
  export * from './queries/fulfilment.queries.js'
27
27
  export * from './queries/concession-proof.queries.js'
28
28
  export * from './queries/pocl-validation-error.queries.js'
29
+ export * from './queries/recurring-payments.queries.js'
29
30
 
30
31
  // Framework functionality
31
32
  export * from './client/util.js'
@@ -0,0 +1,31 @@
1
+ import { findDueRecurringPayments } from '../recurring-payments.queries.js'
2
+
3
+ describe('Recurring Payment Queries', () => {
4
+ describe('findDueRecurringPayments', () => {
5
+ it('builds a query to retrieve active recurring payments', () => {
6
+ const date = new Date('2023-11-08')
7
+
8
+ const query = findDueRecurringPayments(date)
9
+
10
+ expect(query.toRetrieveRequest()).toEqual({
11
+ collection: 'defra_recurringpayments',
12
+ filter:
13
+ "Microsoft.Dynamics.CRM.On(PropertyName='defra_nextduedate', PropertyValue='Wed Nov 08 2023 00:00:00 GMT+0000 (Greenwich Mean Time)')",
14
+ select: [
15
+ 'defra_recurringpaymentid',
16
+ 'defra_name',
17
+ 'statecode',
18
+ 'defra_nextduedate',
19
+ 'defra_cancelleddate',
20
+ 'defra_cancelledreason',
21
+ 'defra_enddate',
22
+ 'defra_agreementid',
23
+ '_defra_activepermission_value',
24
+ '_defra_contact_value',
25
+ 'defra_publicid'
26
+ ],
27
+ expand: [{ property: 'defra_Contact' }, { property: 'defra_ActivePermission' }]
28
+ })
29
+ })
30
+ })
31
+ })
@@ -0,0 +1,20 @@
1
+ import { RecurringPayment } from '../entities/recurring-payment.entity.js'
2
+ import { PredefinedQuery } from './predefined-query.js'
3
+
4
+ /**
5
+ * Builds a query to retrieve active recurring payment and related entities for a given date
6
+ *
7
+ * @param date current date used for lookup
8
+ * @returns {PredefinedQuery}
9
+ */
10
+ export const findDueRecurringPayments = date => {
11
+ const { contact, activePermission } = RecurringPayment.definition.relationships
12
+
13
+ const filter = `Microsoft.Dynamics.CRM.On(PropertyName='defra_nextduedate', PropertyValue='${date}')`
14
+
15
+ return new PredefinedQuery({
16
+ root: RecurringPayment,
17
+ filter: filter,
18
+ expand: [contact, activePermission]
19
+ })
20
+ }