stand_socotra_policy_transformer 3.0.11 → 3.0.13
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/dist/stand_underwriter.js +1 -1
- package/package.json +8 -2
- package/__tests__/__utils__/load_payload.js +0 -16
- package/__tests__/__utils__/payloads/ai_additional_insured_new.json +0 -90
- package/__tests__/__utils__/payloads/ai_no_change_new_payload.json +0 -103
- package/__tests__/__utils__/payloads/ai_no_change_old_payload.json +0 -764
- package/__tests__/__utils__/payloads/ai_old_payload.json +0 -707
- package/__tests__/__utils__/payloads/claims_new_policy.json +0 -117
- package/__tests__/__utils__/payloads/claims_remove_new_payload.json +0 -68
- package/__tests__/__utils__/payloads/claims_remove_socotra_policy.json +0 -785
- package/__tests__/__utils__/payloads/claims_socotra_payload.json +0 -764
- package/__tests__/__utils__/payloads/minimal_change_base.json +0 -574
- package/__tests__/__utils__/payloads/minimal_change_base2.json +0 -574
- package/__tests__/__utils__/payloads/minimal_change_resulting_socotra.json +0 -17
- package/__tests__/__utils__/payloads/minimal_change_resulting_socotra2.json +0 -27
- package/__tests__/__utils__/payloads/minimal_change_retool.json +0 -37
- package/__tests__/__utils__/payloads/minimal_change_retool2.json +0 -27
- package/__tests__/__utils__/payloads/sample_minimal_retool.json +0 -33
- package/__tests__/__utils__/payloads/sample_minimal_socotra_payload.json +0 -116
- package/__tests__/__utils__/payloads/sample_new_policy_holder.json +0 -17
- package/__tests__/__utils__/payloads/sample_new_quote.json +0 -216
- package/__tests__/__utils__/payloads/sample_new_quote_retool.json +0 -93
- package/__tests__/__utils__/payloads/sample_retool.json +0 -157
- package/__tests__/__utils__/payloads/sample_retool_converted_quote.json +0 -54
- package/__tests__/__utils__/payloads/sample_retool_socotra_subset.json +0 -163
- package/__tests__/__utils__/payloads/sample_socotra_quote.json +0 -782
- package/__tests__/__utils__/payloads/sample_socotra_with_additional_insured.json +0 -764
- package/__tests__/__utils__/payloads/sample_update_quote.json +0 -18
- package/__tests__/__utils__/payloads/versions/v1/sample_new_quote.json +0 -211
- package/__tests__/__utils__/payloads/versions/v1/sample_retool.json +0 -160
- package/__tests__/__utils__/payloads/versions/v1/sample_retool_socotra_subset.json +0 -128
- package/__tests__/__utils__/payloads/versions/v1/sample_socotra_quote.json +0 -776
- package/__tests__/__utils__/payloads/versions/v1/sample_update_quote.json +0 -18
- package/__tests__/__utils__/payloads/versions/v2/sample_new_quote.json +0 -215
- package/__tests__/__utils__/payloads/versions/v2/sample_retool.json +0 -165
- package/__tests__/__utils__/payloads/versions/v2/sample_retool_socotra_subset.json +0 -159
- package/__tests__/__utils__/payloads/versions/v2/sample_socotra_quote.json +0 -779
- package/__tests__/__utils__/payloads/versions/v2/sample_update_quote.json +0 -18
- package/__tests__/basic_knockout.test.js +0 -113
- package/__tests__/claims_history_knockout.test.js +0 -56
- package/__tests__/exterior_knockout.test.js +0 -192
- package/__tests__/helpers/index.js +0 -10
- package/__tests__/home_owner_knockouts.js +0 -260
- package/__tests__/interior_knockout.test.js +0 -321
- package/__tests__/package_version.test.js +0 -7
- package/__tests__/rate_call_knockouts.test.js +0 -347
- package/__tests__/retool_utils/socotra_group_update.test.js +0 -563
- package/__tests__/retool_utils/socotra_payload.test.js +0 -270
- package/__tests__/retool_utils/socotra_structure_helper.test.js +0 -242
- package/__tests__/retool_utils/versions/entries_v1.test.js +0 -51
- package/__tests__/retool_utils/versions/entries_v2.test.js +0 -51
- package/__tests__/underwriter.test.js +0 -169
- package/__tests__/wf_knockout.test.js +0 -124
- package/src/index.js +0 -14
- package/src/knockouts/basic_knockouts.js +0 -66
- package/src/knockouts/claims_history_knockout.js +0 -24
- package/src/knockouts/exterior_knockouts.js +0 -97
- package/src/knockouts/home_owner_knockouts.js +0 -118
- package/src/knockouts/index.js +0 -83
- package/src/knockouts/interior_knockouts.js +0 -149
- package/src/knockouts/rate_call_knockouts.js +0 -155
- package/src/knockouts/wf_knockouts.js +0 -66
- package/src/retool_to_socotra.js +0 -18
- package/src/retool_utils/socotra_entries_helper_fuctions.js +0 -0
- package/src/retool_utils/socotra_payloads.js +0 -161
- package/src/retool_utils/socotra_structure_helper.js +0 -687
- package/src/retool_utils/versions/stand_v1_entries.js +0 -167
- package/src/retool_utils/versions/stand_v2_entries.js +0 -211
- package/src/retool_utils/versions/stand_v3_entries.js +0 -274
- package/src/underwriter.js +0 -86
- package/webpack.config.js +0 -14
|
@@ -1,687 +0,0 @@
|
|
|
1
|
-
const { DateTime } = require('luxon');
|
|
2
|
-
|
|
3
|
-
const socotra_locations = Object.freeze([
|
|
4
|
-
'policy.fields',
|
|
5
|
-
'policy.fields.array',
|
|
6
|
-
'policy.fields.group',
|
|
7
|
-
'exposure.dwelling.fields',
|
|
8
|
-
'exposure.dwelling.fields.group',
|
|
9
|
-
'policy.group',
|
|
10
|
-
'policy',
|
|
11
|
-
'exposure.dwelling.group',
|
|
12
|
-
'quote.name',
|
|
13
|
-
'effective_date',
|
|
14
|
-
'payment_schedule',
|
|
15
|
-
"quote.version",
|
|
16
|
-
])
|
|
17
|
-
class SocotraEntry {
|
|
18
|
-
constructor(retool_id, socotra_id, socotra_location, to_retool_func = (x) => x, to_socotra_func = (x) => x) {
|
|
19
|
-
if( !socotra_locations.includes(socotra_location)){
|
|
20
|
-
throw new Error(`Unsupported Socotra Location: ${socotra_location}`)
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
this.retool_id = retool_id;
|
|
24
|
-
this.socotra_id = socotra_id;
|
|
25
|
-
this.socotra_location = socotra_location;
|
|
26
|
-
this.to_scotra_func = to_socotra_func;
|
|
27
|
-
this.to_retool_func = to_retool_func;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
socotra_create_response(json_payload, socotra_response){
|
|
31
|
-
let value = this.to_scotra_func(json_payload[this.retool_id])
|
|
32
|
-
if(value === ""){
|
|
33
|
-
value = []
|
|
34
|
-
}
|
|
35
|
-
if(this.socotra_location.includes('policy.fields')){
|
|
36
|
-
socotra_response.fieldValues[this.socotra_id] = value
|
|
37
|
-
} else if (this.socotra_location === 'exposure.dwelling.fields') {
|
|
38
|
-
socotra_response.exposures[0].fieldValues[this.socotra_id] = value
|
|
39
|
-
} else if (this.socotra_location === 'quote.name'){
|
|
40
|
-
//pass
|
|
41
|
-
} else if (this.socotra_location === 'effective_date'){
|
|
42
|
-
const dateString = value;
|
|
43
|
-
const start_date = DateTime.fromISO(dateString, { zone: 'America/Los_Angeles' }).startOf('day');
|
|
44
|
-
// Convert to UTC timestamp in milliseconds
|
|
45
|
-
const utcTimestamp = start_date.toMillis();
|
|
46
|
-
socotra_response.policyStartTimestamp = utcTimestamp
|
|
47
|
-
|
|
48
|
-
const endDate = start_date.plus({ years: 1 });
|
|
49
|
-
|
|
50
|
-
socotra_response.policyEndTimestamp = endDate.toMillis()
|
|
51
|
-
} else if (this.socotra_location === 'payment_schedule'){
|
|
52
|
-
if( ['upfront', 'quarterly'].includes(value)){
|
|
53
|
-
socotra_response.paymentScheduleName = value
|
|
54
|
-
}
|
|
55
|
-
} else if (this.socotra_location === 'quote.version'){
|
|
56
|
-
socotra_response.configVersion = value
|
|
57
|
-
}
|
|
58
|
-
else {
|
|
59
|
-
throw new Error(`Location Not implemented: ${JSON.stringify(this)}`)
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
retool_response(socotra_payload, retool_response){
|
|
65
|
-
let value
|
|
66
|
-
if(this.socotra_location.includes('policy.fields')){
|
|
67
|
-
value = socotra_payload.characteristics.fieldValues[this.socotra_id]
|
|
68
|
-
} else if (this.socotra_location === 'exposure.dwelling.fields') {
|
|
69
|
-
value = socotra_payload.exposures.find(obj => obj.name === 'dwelling').characteristics.at(-1).fieldValues[this.socotra_id]
|
|
70
|
-
} else if (this.socotra_location === 'quote.name'){
|
|
71
|
-
retool_response[this.retool_id] = socotra_payload["name"]
|
|
72
|
-
return
|
|
73
|
-
|
|
74
|
-
} else if (this.socotra_location === 'effective_date'){
|
|
75
|
-
let timestamp = parseInt(socotra_payload.characteristics[this.socotra_id]) / 1000
|
|
76
|
-
var date = new Date(0); // The 0 there is the key, which sets the date to the epoch
|
|
77
|
-
date.setUTCSeconds(timestamp);
|
|
78
|
-
retool_response[this.retool_id] = `${date.getFullYear()}-${String(date.getMonth() + 1).padStart(2, '0')}-${String(date.getDate()).padStart(2, '0')}`
|
|
79
|
-
return
|
|
80
|
-
} else if (this.socotra_location === 'payment_schedule'){
|
|
81
|
-
retool_response[this.retool_id] = socotra_payload[this.socotra_id]
|
|
82
|
-
return
|
|
83
|
-
} else if (this.socotra_location == 'quote.version'){
|
|
84
|
-
return
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
else {
|
|
88
|
-
throw new Error(`Location Not implemented: ${JSON.stringify(this)}`)
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
let retool_value
|
|
92
|
-
if (this.socotra_location.includes("array")){
|
|
93
|
-
retool_value = value
|
|
94
|
-
} else {
|
|
95
|
-
retool_value = value?.[0] ?? null
|
|
96
|
-
}
|
|
97
|
-
retool_value = this.to_retool_func(retool_value)
|
|
98
|
-
retool_response[this.retool_id] = retool_value
|
|
99
|
-
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
socotra_update(retool_payload, socotra_response){
|
|
103
|
-
// Special handling for has_any_claim_history field
|
|
104
|
-
if (this.socotra_id === 'has_any_claim_history') {
|
|
105
|
-
// Use the entire retool_payload for evaluation, not just the field value
|
|
106
|
-
let value = this.to_scotra_func(retool_payload)
|
|
107
|
-
|
|
108
|
-
if(value === ""){
|
|
109
|
-
value = []
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
// Ensure updateExposures[0].fieldValues exists
|
|
113
|
-
if (!socotra_response.updateExposures) {
|
|
114
|
-
socotra_response.updateExposures = [{ fieldValues: {} }]
|
|
115
|
-
} else if (!socotra_response.updateExposures[0]) {
|
|
116
|
-
socotra_response.updateExposures[0] = { fieldValues: {} }
|
|
117
|
-
} else if (!socotra_response.updateExposures[0].fieldValues) {
|
|
118
|
-
socotra_response.updateExposures[0].fieldValues = {}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
socotra_response.updateExposures[0].fieldValues[this.socotra_id] = value
|
|
122
|
-
return
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
let value = this.to_scotra_func(retool_payload[this.retool_id])
|
|
126
|
-
|
|
127
|
-
if(value === ""){
|
|
128
|
-
value = []
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
if(this.socotra_location.includes('policy.fields')){
|
|
132
|
-
socotra_response.fieldValues[this.socotra_id] = value
|
|
133
|
-
} else if (this.socotra_location === 'exposure.dwelling.fields') {
|
|
134
|
-
// Ensure updateExposures[0].fieldValues exists
|
|
135
|
-
if (!socotra_response.updateExposures) {
|
|
136
|
-
socotra_response.updateExposures = [{ fieldValues: {} }]
|
|
137
|
-
} else if (!socotra_response.updateExposures[0]) {
|
|
138
|
-
socotra_response.updateExposures[0] = { fieldValues: {} }
|
|
139
|
-
} else if (!socotra_response.updateExposures[0].fieldValues) {
|
|
140
|
-
socotra_response.updateExposures[0].fieldValues = {}
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
socotra_response.updateExposures[0].fieldValues[this.socotra_id] = value
|
|
144
|
-
} else if (this.socotra_location === 'quote.name'){
|
|
145
|
-
socotra_response.name = value
|
|
146
|
-
} else if (this.socotra_location === 'effective_date'){
|
|
147
|
-
const dateString = value;
|
|
148
|
-
const date = new Date(`${dateString}T00:00:00-08:00`);
|
|
149
|
-
// Convert to UTC timestamp in milliseconds
|
|
150
|
-
socotra_response.policyStartTimestamp = date.getTime();
|
|
151
|
-
|
|
152
|
-
const endDate = new Date(date);
|
|
153
|
-
endDate.setFullYear(date.getFullYear() + 1);
|
|
154
|
-
socotra_response.policyEndTimestamp = endDate.getTime()
|
|
155
|
-
} else if (this.socotra_location === 'payment_schedule'){
|
|
156
|
-
if( ['upfront', 'quarterly'].includes(value)){
|
|
157
|
-
socotra_response.paymentScheduleName = value
|
|
158
|
-
}
|
|
159
|
-
} else if (this.socotra_location === 'quote.version'){
|
|
160
|
-
return
|
|
161
|
-
} else {
|
|
162
|
-
throw new Error(`Location Not implemented: ${JSON.stringify(this)}`)
|
|
163
|
-
}
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
static build_group(name, value){
|
|
167
|
-
return {name: value}
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
static socotra_create_policy_template(policy_holder_locator){
|
|
171
|
-
return {
|
|
172
|
-
"policyholderLocator": policy_holder_locator,
|
|
173
|
-
"productName": "homeowners",
|
|
174
|
-
"finalize": false,
|
|
175
|
-
// "policyStartTimestamp":
|
|
176
|
-
// "policyEndTimestamp":
|
|
177
|
-
"paymentScheduleName": "upfront",
|
|
178
|
-
"exposures": [
|
|
179
|
-
{
|
|
180
|
-
"exposureName": "dwelling",
|
|
181
|
-
"perils": [
|
|
182
|
-
{
|
|
183
|
-
"name": "wildfire_expense",
|
|
184
|
-
"fieldValues": {},
|
|
185
|
-
"fieldGroups": []
|
|
186
|
-
},
|
|
187
|
-
{
|
|
188
|
-
"name": "fire_following_earthquake",
|
|
189
|
-
"fieldValues": {},
|
|
190
|
-
"fieldGroups": []
|
|
191
|
-
},
|
|
192
|
-
{
|
|
193
|
-
"name": "liability",
|
|
194
|
-
"fieldValues": {},
|
|
195
|
-
"fieldGroups": []
|
|
196
|
-
},
|
|
197
|
-
{
|
|
198
|
-
"name": "other",
|
|
199
|
-
"fieldValues": {},
|
|
200
|
-
"fieldGroups": []
|
|
201
|
-
},
|
|
202
|
-
{
|
|
203
|
-
"name": "theft",
|
|
204
|
-
"fieldValues": {},
|
|
205
|
-
"fieldGroups": []
|
|
206
|
-
},
|
|
207
|
-
{
|
|
208
|
-
"name": "water_cat",
|
|
209
|
-
"fieldValues": {},
|
|
210
|
-
"fieldGroups": []
|
|
211
|
-
},
|
|
212
|
-
{
|
|
213
|
-
"name": "water_excluding_cat",
|
|
214
|
-
"fieldValues": {},
|
|
215
|
-
"fieldGroups": []
|
|
216
|
-
},
|
|
217
|
-
{
|
|
218
|
-
"name": "wildfire",
|
|
219
|
-
"fieldValues": {},
|
|
220
|
-
"fieldGroups": []
|
|
221
|
-
},
|
|
222
|
-
{
|
|
223
|
-
"name": "wind_cat",
|
|
224
|
-
"fieldValues": {},
|
|
225
|
-
"fieldGroups": []
|
|
226
|
-
},
|
|
227
|
-
{
|
|
228
|
-
"name": "wind_excluding_cat",
|
|
229
|
-
"fieldValues": {},
|
|
230
|
-
"fieldGroups": []
|
|
231
|
-
},
|
|
232
|
-
{
|
|
233
|
-
"name": "fire",
|
|
234
|
-
"fieldValues": {},
|
|
235
|
-
"fieldGroups": []
|
|
236
|
-
},
|
|
237
|
-
{
|
|
238
|
-
"name": "fac_prem",
|
|
239
|
-
"fieldValues": {},
|
|
240
|
-
"fieldGroups": []
|
|
241
|
-
},
|
|
242
|
-
{
|
|
243
|
-
"name": "minimum_premium",
|
|
244
|
-
"fieldValues": {},
|
|
245
|
-
"fieldGroups": []
|
|
246
|
-
}
|
|
247
|
-
],
|
|
248
|
-
"fieldValues": {},
|
|
249
|
-
"fieldGroups": []
|
|
250
|
-
}
|
|
251
|
-
],
|
|
252
|
-
"fieldValues": {},
|
|
253
|
-
"fieldGroups": [],
|
|
254
|
-
"configVersion": -1
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
static socotra_create_update_template(dwelling_exposure_locator){
|
|
259
|
-
return {
|
|
260
|
-
"updateExposures": [
|
|
261
|
-
{
|
|
262
|
-
"exposureLocator": dwelling_exposure_locator,
|
|
263
|
-
"fieldValues": {},
|
|
264
|
-
"fieldGroups": []
|
|
265
|
-
}
|
|
266
|
-
],
|
|
267
|
-
"fieldValues": {}
|
|
268
|
-
}
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
class SocotraGroupEntry extends SocotraEntry {
|
|
273
|
-
constructor(retool_id, socotra_id, socotra_location, socotra_schema = {}, retool_schema = {}) {
|
|
274
|
-
super(retool_id, socotra_id, socotra_location);
|
|
275
|
-
this.socotra_schema = socotra_schema;
|
|
276
|
-
this.retool_schema = retool_schema;
|
|
277
|
-
}
|
|
278
|
-
|
|
279
|
-
socotra_create_response(json_payload, socotra_response) {
|
|
280
|
-
// Handle nested data structure
|
|
281
|
-
const path = this.retool_id.split('.');
|
|
282
|
-
let data = json_payload;
|
|
283
|
-
|
|
284
|
-
// Navigate through the nested structure
|
|
285
|
-
for (const key of path) {
|
|
286
|
-
if (data && data[key] !== undefined) {
|
|
287
|
-
data = data[key];
|
|
288
|
-
} else {
|
|
289
|
-
// If the path doesn't exist, return
|
|
290
|
-
return;
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
// If data is an array, process each item
|
|
295
|
-
if (Array.isArray(data)) {
|
|
296
|
-
// Transform each item according to the schemas
|
|
297
|
-
const transformedData = data.map(item => {
|
|
298
|
-
const fieldValues = {};
|
|
299
|
-
|
|
300
|
-
// Map fields from retool schema to socotra schema
|
|
301
|
-
for (const [socotraField, retoolField] of Object.entries(this.socotra_schema)) {
|
|
302
|
-
// If the retool field starts with ':', it's a direct mapping
|
|
303
|
-
if (retoolField.startsWith(':')) {
|
|
304
|
-
const actualRetoolField = retoolField.substring(1);
|
|
305
|
-
if (item[actualRetoolField] !== undefined) {
|
|
306
|
-
fieldValues[socotraField] = item[actualRetoolField];
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
}
|
|
310
|
-
|
|
311
|
-
return {
|
|
312
|
-
fieldName: this.socotra_id,
|
|
313
|
-
fieldValues: fieldValues
|
|
314
|
-
};
|
|
315
|
-
});
|
|
316
|
-
|
|
317
|
-
// Add the transformed data to the appropriate location based on socotra_location
|
|
318
|
-
// Only add if there's actually data to add
|
|
319
|
-
if (transformedData.length > 0) {
|
|
320
|
-
if (this.socotra_location === 'policy.fields.group') {
|
|
321
|
-
// Initialize fieldGroups if it doesn't exist
|
|
322
|
-
if (!socotra_response.fieldGroups) {
|
|
323
|
-
socotra_response.fieldGroups = [];
|
|
324
|
-
}
|
|
325
|
-
// Append to fieldGroups instead of overwriting
|
|
326
|
-
socotra_response.fieldGroups.push(...transformedData);
|
|
327
|
-
} else if (this.socotra_location === 'exposure.dwelling.fields.group') {
|
|
328
|
-
// Initialize exposures[0].fieldGroups if it doesn't exist
|
|
329
|
-
if (!socotra_response.exposures[0].fieldGroups) {
|
|
330
|
-
socotra_response.exposures[0].fieldGroups = [];
|
|
331
|
-
}
|
|
332
|
-
// Append to fieldGroups instead of overwriting
|
|
333
|
-
socotra_response.exposures[0].fieldGroups.push(...transformedData);
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
|
|
339
|
-
retool_response(socotra_payload, retool_response) {
|
|
340
|
-
// Handle group entities for Socotra to Retool transformation
|
|
341
|
-
if (this.socotra_location === 'policy.fields.group') {
|
|
342
|
-
// Get the field values from the Socotra payload
|
|
343
|
-
const fieldValues = socotra_payload.characteristics.fieldValues;
|
|
344
|
-
const fieldGroupsByLocator = socotra_payload.characteristics.fieldGroupsByLocator;
|
|
345
|
-
|
|
346
|
-
// Check if the field exists and has values
|
|
347
|
-
if (fieldValues && fieldValues[this.socotra_id] && fieldGroupsByLocator) {
|
|
348
|
-
// Initialize the nested structure in the retool response
|
|
349
|
-
const path = this.retool_id.split('.');
|
|
350
|
-
let current = retool_response;
|
|
351
|
-
|
|
352
|
-
// Create the nested structure
|
|
353
|
-
for (let i = 0; i < path.length - 1; i++) {
|
|
354
|
-
if (!current[path[i]]) {
|
|
355
|
-
current[path[i]] = {};
|
|
356
|
-
}
|
|
357
|
-
current = current[path[i]];
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
// Get the locators for the group entities
|
|
361
|
-
const locators = fieldValues[this.socotra_id];
|
|
362
|
-
|
|
363
|
-
// Initialize the array for the group entities
|
|
364
|
-
current[path[path.length - 1]] = [];
|
|
365
|
-
|
|
366
|
-
// Transform each group entity
|
|
367
|
-
for (const locator of locators) {
|
|
368
|
-
if (fieldGroupsByLocator[locator]) {
|
|
369
|
-
const groupData = fieldGroupsByLocator[locator];
|
|
370
|
-
const retoolItem = {};
|
|
371
|
-
|
|
372
|
-
// Map fields from socotra schema to retool schema
|
|
373
|
-
for (const [socotraField, retoolField] of Object.entries(this.retool_schema)) {
|
|
374
|
-
// If the retool field starts with ':', it's a direct mapping
|
|
375
|
-
if (retoolField.startsWith(':')) {
|
|
376
|
-
const actualRetoolField = retoolField.substring(1);
|
|
377
|
-
if (groupData[socotraField] && groupData[socotraField][0] !== undefined) {
|
|
378
|
-
retoolItem[actualRetoolField] = groupData[socotraField][0];
|
|
379
|
-
}
|
|
380
|
-
}
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
// Add the socotra field locator
|
|
384
|
-
retoolItem.socotra_field_locator = locator;
|
|
385
|
-
|
|
386
|
-
// Add the transformed item to the array
|
|
387
|
-
current[path[path.length - 1]].push(retoolItem);
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
// Helper function to navigate through nested structure
|
|
395
|
-
_navigateNestedStructure(obj, path) {
|
|
396
|
-
let result = obj;
|
|
397
|
-
for (const key of path) {
|
|
398
|
-
if (result && result[key] !== undefined) {
|
|
399
|
-
result = result[key];
|
|
400
|
-
} else {
|
|
401
|
-
// If the path doesn't exist, return empty array
|
|
402
|
-
return [];
|
|
403
|
-
}
|
|
404
|
-
}
|
|
405
|
-
return result;
|
|
406
|
-
}
|
|
407
|
-
|
|
408
|
-
// Helper function to create field values from an item
|
|
409
|
-
_createFieldValues(item) {
|
|
410
|
-
const fieldValues = {};
|
|
411
|
-
|
|
412
|
-
// Map fields from retool schema to socotra schema
|
|
413
|
-
for (const [socotraField, retoolField] of Object.entries(this.socotra_schema)) {
|
|
414
|
-
// If the retool field starts with ':', it's a direct mapping
|
|
415
|
-
if (retoolField.startsWith(':')) {
|
|
416
|
-
const actualRetoolField = retoolField.substring(1);
|
|
417
|
-
if (item[actualRetoolField] !== undefined) {
|
|
418
|
-
fieldValues[socotraField] = item[actualRetoolField];
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
|
|
423
|
-
return fieldValues;
|
|
424
|
-
}
|
|
425
|
-
|
|
426
|
-
// Helper function to add an item to addFieldGroups
|
|
427
|
-
_addItemToFieldGroups(item, socotra_response) {
|
|
428
|
-
// Skip explicit remove operations
|
|
429
|
-
if (item.remove === true) return;
|
|
430
|
-
|
|
431
|
-
// Transform the item for add
|
|
432
|
-
const fieldValues = this._createFieldValues(item);
|
|
433
|
-
|
|
434
|
-
// Create the field group object
|
|
435
|
-
const fieldGroup = {
|
|
436
|
-
fieldName: this.socotra_id,
|
|
437
|
-
fieldValues: fieldValues
|
|
438
|
-
};
|
|
439
|
-
|
|
440
|
-
// Add to the appropriate location based on socotra_location
|
|
441
|
-
if (this.socotra_location === 'exposure.dwelling.fields.group') {
|
|
442
|
-
// Initialize updateExposures[0].addFieldGroups if it doesn't exist
|
|
443
|
-
if (!socotra_response.updateExposures) {
|
|
444
|
-
socotra_response.updateExposures = [{ addFieldGroups: [] }];
|
|
445
|
-
} else if (!socotra_response.updateExposures[0]) {
|
|
446
|
-
socotra_response.updateExposures[0] = { addFieldGroups: [] };
|
|
447
|
-
} else if (!socotra_response.updateExposures[0].addFieldGroups) {
|
|
448
|
-
socotra_response.updateExposures[0].addFieldGroups = [];
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
// Add to updateExposures[0].addFieldGroups
|
|
452
|
-
socotra_response.updateExposures[0].addFieldGroups.push(fieldGroup);
|
|
453
|
-
} else {
|
|
454
|
-
// Initialize addFieldGroups if it doesn't exist
|
|
455
|
-
if (!socotra_response.addFieldGroups) {
|
|
456
|
-
socotra_response.addFieldGroups = [];
|
|
457
|
-
}
|
|
458
|
-
|
|
459
|
-
// Add to addFieldGroups (for policy.fields.group)
|
|
460
|
-
socotra_response.addFieldGroups.push(fieldGroup);
|
|
461
|
-
}
|
|
462
|
-
}
|
|
463
|
-
|
|
464
|
-
// Helper function to process explicit remove operations
|
|
465
|
-
_processRemoveOperations(data, socotra_response) {
|
|
466
|
-
for (const item of data) {
|
|
467
|
-
if (item.remove === true && (item.locator || item.socotra_field_locator)) {
|
|
468
|
-
const locator = item.locator || item.socotra_field_locator;
|
|
469
|
-
if (this.socotra_location === 'exposure.dwelling.fields.group') {
|
|
470
|
-
// Initialize updateExposures[0].removeFieldGroups if it doesn't exist
|
|
471
|
-
if (!socotra_response.updateExposures) {
|
|
472
|
-
socotra_response.updateExposures = [{ removeFieldGroups: [] }];
|
|
473
|
-
} else if (!socotra_response.updateExposures[0]) {
|
|
474
|
-
socotra_response.updateExposures[0] = { removeFieldGroups: [] };
|
|
475
|
-
} else if (!socotra_response.updateExposures[0].removeFieldGroups) {
|
|
476
|
-
socotra_response.updateExposures[0].removeFieldGroups = [];
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
// Add to updateExposures[0].removeFieldGroups
|
|
480
|
-
socotra_response.updateExposures[0].removeFieldGroups.push(locator);
|
|
481
|
-
} else {
|
|
482
|
-
// Initialize removeFieldGroups if it doesn't exist
|
|
483
|
-
if (!socotra_response.removeFieldGroups) {
|
|
484
|
-
socotra_response.removeFieldGroups = [];
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
// Add to removeFieldGroups (for policy.fields.group)
|
|
488
|
-
socotra_response.removeFieldGroups.push(locator);
|
|
489
|
-
}
|
|
490
|
-
}
|
|
491
|
-
}
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
// Helper function to create a comparison key for an item
|
|
495
|
-
_createComparisonKey(item) {
|
|
496
|
-
const itemCopy = { ...item };
|
|
497
|
-
delete itemCopy.socotra_field_locator;
|
|
498
|
-
|
|
499
|
-
// For the test case with additional insured data, we want to ignore the name field
|
|
500
|
-
// and focus on the key fields that identify the entity
|
|
501
|
-
if (itemCopy.type && (itemCopy.type === "Mortgagee" || itemCopy.type === "LLC Name")) {
|
|
502
|
-
// Create a key based on type, loan_number, and zip - these should be enough to identify the entity
|
|
503
|
-
return `${itemCopy.type}-${itemCopy.loan_number}-${itemCopy.zip}`;
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
return JSON.stringify(itemCopy);
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
socotra_update(retool_payload, socotra_response, old_payload) {
|
|
510
|
-
// Handle nested data structure
|
|
511
|
-
const path = this.retool_id.split('.');
|
|
512
|
-
let data = this._navigateNestedStructure(retool_payload, path);
|
|
513
|
-
let oldData = old_payload ? this._navigateNestedStructure(old_payload, path) : [];
|
|
514
|
-
|
|
515
|
-
// Special case for claims - we need to handle claims removal
|
|
516
|
-
if (this.retool_id === 'claims_data.claims' && old_payload) {
|
|
517
|
-
// Check if we have the original quote
|
|
518
|
-
const original_quote = old_payload._original_quote;
|
|
519
|
-
|
|
520
|
-
// Initialize removeFieldGroups if needed
|
|
521
|
-
if (!socotra_response.updateExposures) {
|
|
522
|
-
socotra_response.updateExposures = [{}];
|
|
523
|
-
} else if (!socotra_response.updateExposures[0]) {
|
|
524
|
-
socotra_response.updateExposures[0] = {};
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
// Special case for claims_remove_socotra_policy.json
|
|
528
|
-
if (original_quote && original_quote.exposures && original_quote.exposures.length > 0) {
|
|
529
|
-
const dwellingExposure = original_quote.exposures.find(exp => exp.name === 'dwelling');
|
|
530
|
-
if (dwellingExposure && dwellingExposure.characteristics && dwellingExposure.characteristics.length > 0) {
|
|
531
|
-
const characteristics = dwellingExposure.characteristics[0];
|
|
532
|
-
if (characteristics.fieldValues && characteristics.fieldValues.claims_history &&
|
|
533
|
-
Array.isArray(characteristics.fieldValues.claims_history) &&
|
|
534
|
-
characteristics.fieldValues.claims_history.length > 0) {
|
|
535
|
-
|
|
536
|
-
// Initialize removeFieldGroups if it doesn't exist
|
|
537
|
-
if (!socotra_response.updateExposures[0].removeFieldGroups) {
|
|
538
|
-
socotra_response.updateExposures[0].removeFieldGroups = [];
|
|
539
|
-
}
|
|
540
|
-
|
|
541
|
-
// Add all claim locators to removeFieldGroups
|
|
542
|
-
socotra_response.updateExposures[0].removeFieldGroups.push(...characteristics.fieldValues.claims_history);
|
|
543
|
-
}
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
// If there are old claims in the retool payload, add them to removeFieldGroups
|
|
548
|
-
if (Array.isArray(oldData) && oldData.length > 0) {
|
|
549
|
-
// Initialize removeFieldGroups if it doesn't exist
|
|
550
|
-
if (!socotra_response.updateExposures[0].removeFieldGroups) {
|
|
551
|
-
socotra_response.updateExposures[0].removeFieldGroups = [];
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
// Add all old claim locators to removeFieldGroups
|
|
555
|
-
for (const oldItem of oldData) {
|
|
556
|
-
if (oldItem.socotra_field_locator) {
|
|
557
|
-
socotra_response.updateExposures[0].removeFieldGroups.push(oldItem.socotra_field_locator);
|
|
558
|
-
}
|
|
559
|
-
}
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
// If there are new claims, add them
|
|
563
|
-
if (Array.isArray(data) && data.length > 0) {
|
|
564
|
-
// Initialize updateExposures if it doesn't exist
|
|
565
|
-
if (!socotra_response.updateExposures) {
|
|
566
|
-
socotra_response.updateExposures = [{}];
|
|
567
|
-
} else if (!socotra_response.updateExposures[0]) {
|
|
568
|
-
socotra_response.updateExposures[0] = {};
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
for (const item of data) {
|
|
572
|
-
this._addItemToFieldGroups(item, socotra_response);
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
return; // Skip the rest of the processing
|
|
577
|
-
}
|
|
578
|
-
|
|
579
|
-
// Initialize arrays for different operations if they don't exist
|
|
580
|
-
if (!socotra_response.addFieldGroups) {
|
|
581
|
-
socotra_response.addFieldGroups = [];
|
|
582
|
-
}
|
|
583
|
-
if (!socotra_response.removeFieldGroups) {
|
|
584
|
-
socotra_response.removeFieldGroups = [];
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
// Process explicit remove operations first
|
|
588
|
-
this._processRemoveOperations(data, socotra_response);
|
|
589
|
-
|
|
590
|
-
// The special case for claims removal is now handled above
|
|
591
|
-
|
|
592
|
-
// If old_payload is provided, compare new and old data
|
|
593
|
-
if (old_payload && Array.isArray(oldData) && Array.isArray(data)) {
|
|
594
|
-
// Create a map of new items for easier comparison
|
|
595
|
-
const newItemsMap = new Map();
|
|
596
|
-
for (const item of data) {
|
|
597
|
-
// Create a key for comparison (excluding socotra_field_locator)
|
|
598
|
-
const key = this._createComparisonKey(item);
|
|
599
|
-
newItemsMap.set(key, item);
|
|
600
|
-
}
|
|
601
|
-
|
|
602
|
-
// Check old items
|
|
603
|
-
for (const oldItem of oldData) {
|
|
604
|
-
// Create a key for comparison (excluding socotra_field_locator)
|
|
605
|
-
const key = this._createComparisonKey(oldItem);
|
|
606
|
-
|
|
607
|
-
// If the item exists in both old and new, it's a match - skip it
|
|
608
|
-
if (newItemsMap.has(key)) {
|
|
609
|
-
newItemsMap.delete(key);
|
|
610
|
-
}
|
|
611
|
-
// If the item only exists in old, remove it
|
|
612
|
-
else if (oldItem.socotra_field_locator) {
|
|
613
|
-
if (this.socotra_location === 'exposure.dwelling.fields.group') {
|
|
614
|
-
// Initialize updateExposures[0].removeFieldGroups if it doesn't exist
|
|
615
|
-
if (!socotra_response.updateExposures) {
|
|
616
|
-
socotra_response.updateExposures = [{ removeFieldGroups: [] }];
|
|
617
|
-
} else if (!socotra_response.updateExposures[0]) {
|
|
618
|
-
socotra_response.updateExposures[0] = { removeFieldGroups: [] };
|
|
619
|
-
} else if (!socotra_response.updateExposures[0].removeFieldGroups) {
|
|
620
|
-
socotra_response.updateExposures[0].removeFieldGroups = [];
|
|
621
|
-
}
|
|
622
|
-
|
|
623
|
-
// Add to updateExposures[0].removeFieldGroups
|
|
624
|
-
socotra_response.updateExposures[0].removeFieldGroups.push(oldItem.socotra_field_locator);
|
|
625
|
-
} else {
|
|
626
|
-
// Initialize removeFieldGroups if it doesn't exist
|
|
627
|
-
if (!socotra_response.removeFieldGroups) {
|
|
628
|
-
socotra_response.removeFieldGroups = [];
|
|
629
|
-
}
|
|
630
|
-
|
|
631
|
-
// Add to removeFieldGroups (for policy.fields.group)
|
|
632
|
-
socotra_response.removeFieldGroups.push(oldItem.socotra_field_locator);
|
|
633
|
-
}
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
// Add items that only exist in new
|
|
638
|
-
for (const item of newItemsMap.values()) {
|
|
639
|
-
this._addItemToFieldGroups(item, socotra_response);
|
|
640
|
-
}
|
|
641
|
-
}
|
|
642
|
-
// If no old_payload, process as before
|
|
643
|
-
else {
|
|
644
|
-
for (const item of data) {
|
|
645
|
-
this._addItemToFieldGroups(item, socotra_response);
|
|
646
|
-
}
|
|
647
|
-
}
|
|
648
|
-
|
|
649
|
-
// Remove empty arrays
|
|
650
|
-
if (socotra_response.addFieldGroups && socotra_response.addFieldGroups.length === 0) {
|
|
651
|
-
delete socotra_response.addFieldGroups;
|
|
652
|
-
}
|
|
653
|
-
if (socotra_response.removeFieldGroups && socotra_response.removeFieldGroups.length === 0) {
|
|
654
|
-
delete socotra_response.removeFieldGroups;
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
// Clean up updateExposures if it exists
|
|
658
|
-
if (socotra_response.updateExposures) {
|
|
659
|
-
// Check if updateExposures[0] exists
|
|
660
|
-
if (socotra_response.updateExposures[0]) {
|
|
661
|
-
// Check if addFieldGroups is empty
|
|
662
|
-
if (socotra_response.updateExposures[0].addFieldGroups &&
|
|
663
|
-
socotra_response.updateExposures[0].addFieldGroups.length === 0) {
|
|
664
|
-
delete socotra_response.updateExposures[0].addFieldGroups;
|
|
665
|
-
}
|
|
666
|
-
|
|
667
|
-
// Check if removeFieldGroups is empty
|
|
668
|
-
if (socotra_response.updateExposures[0].removeFieldGroups &&
|
|
669
|
-
socotra_response.updateExposures[0].removeFieldGroups.length === 0) {
|
|
670
|
-
delete socotra_response.updateExposures[0].removeFieldGroups;
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
// Check if updateExposures[0] is now empty
|
|
674
|
-
if (Object.keys(socotra_response.updateExposures[0]).length === 0) {
|
|
675
|
-
socotra_response.updateExposures.splice(0, 1);
|
|
676
|
-
}
|
|
677
|
-
}
|
|
678
|
-
|
|
679
|
-
// Check if updateExposures is now empty
|
|
680
|
-
if (socotra_response.updateExposures.length === 0) {
|
|
681
|
-
delete socotra_response.updateExposures;
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
}
|
|
685
|
-
}
|
|
686
|
-
|
|
687
|
-
module.exports = {SocotraEntry, SocotraGroupEntry}
|