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
package/src/knockouts/index.js
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
const {
|
|
2
|
-
multi_family_unit_count,
|
|
3
|
-
primary_dwelling_is_insured,
|
|
4
|
-
full_replacement_value,
|
|
5
|
-
prior_carrier, occupation
|
|
6
|
-
} = require('./basic_knockouts')
|
|
7
|
-
|
|
8
|
-
const { wf_variance, stand_wf_knockout } = require('./wf_knockouts');
|
|
9
|
-
const { distance_to_coast, pool_features, farming_type, has_attractive_nuisance,
|
|
10
|
-
degree_of_slope, flood_score} = require('./exterior_knockouts')
|
|
11
|
-
const {number_of_dogs, dog_history, dog_breeds, exotic_pets, number_of_mortgages,
|
|
12
|
-
number_of_bankruptcies_judgements_or_liens, home_business_type, home_rental_type, same_address
|
|
13
|
-
} = require('./home_owner_knockouts')
|
|
14
|
-
const {is_vacant, under_renovation, plumbing_last_update_year,
|
|
15
|
-
water_heater_last_update_year, electrical_last_update_year, home_heating_last_update_year,
|
|
16
|
-
heating_source, has_underground_fuel_tank, has_steel_braided_hose, has_water_shutoff, has_circuit_breaker
|
|
17
|
-
} = require('./interior_knockouts')
|
|
18
|
-
|
|
19
|
-
const {
|
|
20
|
-
construction_type, siding_material, protection_class, roof_material, foundation_type,
|
|
21
|
-
has_slab_foundation_plumbing, fire_protective_devices, theft_protective_devices, has_class_a_roof
|
|
22
|
-
} = require('./rate_call_knockouts')
|
|
23
|
-
|
|
24
|
-
const {check_claims_history} = require('./claims_history_knockout')
|
|
25
|
-
|
|
26
|
-
const questions = {
|
|
27
|
-
"multi_family_unit_count": multi_family_unit_count,
|
|
28
|
-
"primary_dwelling_insured": primary_dwelling_is_insured,
|
|
29
|
-
"full_replacement_value": full_replacement_value,
|
|
30
|
-
"prior_carrier": prior_carrier,
|
|
31
|
-
"wf_variance": wf_variance,
|
|
32
|
-
"flood_score": flood_score,
|
|
33
|
-
"distance_to_coast": distance_to_coast,
|
|
34
|
-
"pool_features": pool_features,
|
|
35
|
-
"number_of_dogs": number_of_dogs,
|
|
36
|
-
"dog_history": dog_history,
|
|
37
|
-
"dog_breeds": dog_breeds,
|
|
38
|
-
"exotic_pets": exotic_pets,
|
|
39
|
-
"farming_type": farming_type,
|
|
40
|
-
"number_of_mortgages": number_of_mortgages,
|
|
41
|
-
"number_of_bankruptcies_judgements_or_liens": number_of_bankruptcies_judgements_or_liens,
|
|
42
|
-
"is_vacant": is_vacant,
|
|
43
|
-
"under_renovation": under_renovation,
|
|
44
|
-
"plumbing_last_update_year": plumbing_last_update_year,
|
|
45
|
-
"water_heater_last_update_year": water_heater_last_update_year,
|
|
46
|
-
"electrical_last_update_year": electrical_last_update_year,
|
|
47
|
-
"home_heating_last_update_year": home_heating_last_update_year,
|
|
48
|
-
"heating_source": heating_source,
|
|
49
|
-
"has_underground_fuel_tank": has_underground_fuel_tank,
|
|
50
|
-
"has_steel_braided_hose": has_steel_braided_hose,
|
|
51
|
-
"has_water_shutoff": has_water_shutoff,
|
|
52
|
-
"home_business_type": home_business_type,
|
|
53
|
-
"has_attractive_nuisance": has_attractive_nuisance,
|
|
54
|
-
"home_rental_type": home_rental_type,
|
|
55
|
-
"degree_of_slope": degree_of_slope,
|
|
56
|
-
"construction_type": construction_type,
|
|
57
|
-
"siding_material": siding_material,
|
|
58
|
-
"protection_class": protection_class,
|
|
59
|
-
"roof_material": roof_material,
|
|
60
|
-
"foundation_type": foundation_type,
|
|
61
|
-
"has_slab_foundation_plumbing": has_slab_foundation_plumbing,
|
|
62
|
-
"fire_protective_devices": fire_protective_devices,
|
|
63
|
-
"theft_protective_devices": theft_protective_devices,
|
|
64
|
-
"occupation": occupation
|
|
65
|
-
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
function knockout(question_name, answer){
|
|
69
|
-
if (questions.hasOwnProperty(question_name)){
|
|
70
|
-
return questions[question_name](answer)
|
|
71
|
-
} else {
|
|
72
|
-
return {decision: "question_not_found", note: null}
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
function knockout_names() {
|
|
77
|
-
return Object.keys(questions)
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
module.exports = {
|
|
81
|
-
knockout, has_circuit_breaker, same_address, knockout_names, stand_wf_knockout, has_class_a_roof,
|
|
82
|
-
check_claims_history
|
|
83
|
-
}
|
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
function is_vacant(vacant){
|
|
2
|
-
if(vacant === 'No'){
|
|
3
|
-
return {decision: "accept", note: null}
|
|
4
|
-
} else if (vacant === 'Yes'){
|
|
5
|
-
return {decision: "reject", note: "Home is vacant"}
|
|
6
|
-
} else {
|
|
7
|
-
return {decision: "reject", note: "Vacant must be yes or no"}
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
function under_renovation(renovation){
|
|
12
|
-
if(renovation === 'No'){
|
|
13
|
-
return {decision: "accept", note: null}
|
|
14
|
-
} else if (renovation === 'Yes'){
|
|
15
|
-
return {decision: "reject", note: "Home is under renovation"}
|
|
16
|
-
} else {
|
|
17
|
-
return {decision: "reject", note: "Under renovation must be yes or no"}
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function plumbing_last_update_year(year_updated){
|
|
22
|
-
if(!Number.isInteger(year_updated)){
|
|
23
|
-
return {decision: "reject", note: "Plumbing year must be an integer"}
|
|
24
|
-
}
|
|
25
|
-
if(year_updated < 1600 || year_updated > 3000){
|
|
26
|
-
return {decision: "reject", note: "Plumbing input should be the year it was last updated not the age"}
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
year_threshold = new Date().getFullYear() - 30
|
|
30
|
-
if(year_updated >= year_threshold){
|
|
31
|
-
return {decision: "accept", note: null}
|
|
32
|
-
} else {
|
|
33
|
-
return {decision: "reject", note: "Plumbing must have been updated in the last 30 years"}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function water_heater_last_update_year(year_updated){
|
|
38
|
-
if(!Number.isInteger(year_updated)){
|
|
39
|
-
return {decision: "reject", note: "Water heater year must be an integer"}
|
|
40
|
-
}
|
|
41
|
-
if(year_updated < 1600 || year_updated > 3000){
|
|
42
|
-
return {decision: "reject", note: "Water heater input should be the year it was last updated not the age"}
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
year_threshold = new Date().getFullYear() - 10
|
|
46
|
-
if(year_updated >= year_threshold){
|
|
47
|
-
return {decision: "accept", note: null}
|
|
48
|
-
} else {
|
|
49
|
-
return {decision: "reject", note: "Water heater must have been updated in the last 10 years"}
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
function electrical_last_update_year(year_updated){
|
|
54
|
-
if(!Number.isInteger(year_updated)){
|
|
55
|
-
return {decision: "reject", note: "Electrical year must be an integer"}
|
|
56
|
-
}
|
|
57
|
-
if(year_updated < 1600 || year_updated > 3000){
|
|
58
|
-
return {decision: "reject", note: "Electrical input should be the year it was last updated not the age"}
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
year_threshold = new Date().getFullYear() - 30
|
|
62
|
-
if(year_updated >= year_threshold){
|
|
63
|
-
return {decision: "accept", note: null}
|
|
64
|
-
} else {
|
|
65
|
-
return {decision: "reject", note: "Electrical must have been updated in the last 30 years"}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function home_heating_last_update_year(year_updated){
|
|
70
|
-
if(!Number.isInteger(year_updated)){
|
|
71
|
-
return {decision: "reject", note: "Home heating year must be an integer"}
|
|
72
|
-
}
|
|
73
|
-
if(year_updated < 1600 || year_updated > 3000){
|
|
74
|
-
return {decision: "reject", note: "Home heating input should be the year it was last updated not the age"}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
year_threshold = new Date().getFullYear() - 30
|
|
78
|
-
if(year_updated >= year_threshold){
|
|
79
|
-
return {decision: "accept", note: null}
|
|
80
|
-
} else {
|
|
81
|
-
return {decision: "reject", note: "Home heating must have been updated in the last 30 years"}
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
function heating_source(heating_type) {
|
|
86
|
-
heating_type_enum = [
|
|
87
|
-
"central gas heat", "thermostatically controlled electrical heat",
|
|
88
|
-
"wood", "coal", "pellet stove"
|
|
89
|
-
]
|
|
90
|
-
|
|
91
|
-
if(typeof heating_type !== 'string'){
|
|
92
|
-
return {decision: "reject", note: "Home heating year must be a string"}
|
|
93
|
-
|
|
94
|
-
} else if(!heating_type_enum.includes(heating_type)){
|
|
95
|
-
return {decision: "reject", note: "Heat source must be in [central gas heat, thermostatically controlled electrical heat, wood, coal, pellet stove]"}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
if(!["wood", "coal", "pellet stove"].includes(heating_type)){
|
|
99
|
-
return {decision: "accept", note: null}
|
|
100
|
-
} else {
|
|
101
|
-
return {decision: "refer", note: null}
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
function has_underground_fuel_tank(has_tank){
|
|
106
|
-
if(has_tank === 'No'){
|
|
107
|
-
return {decision: "accept", note: null}
|
|
108
|
-
} else if (has_tank === 'Yes'){
|
|
109
|
-
return {decision: "reject", note: "Home has underground fuel tank"}
|
|
110
|
-
} else {
|
|
111
|
-
return {decision: "reject", note: "Underground fuel tank must be yes or no"}
|
|
112
|
-
}
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
function has_steel_braided_hose(has_steel){
|
|
116
|
-
if(has_steel === 'Yes'){
|
|
117
|
-
return {decision: "accept", note: null}
|
|
118
|
-
} else if (has_steel === 'No'){
|
|
119
|
-
return {decision: "refer", note: null}
|
|
120
|
-
} else {
|
|
121
|
-
return {decision: "reject", note: "Steel braided hose must be yes or no"}
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function has_water_shutoff(has_shutoff){
|
|
126
|
-
if(has_shutoff === 'Yes'){
|
|
127
|
-
return {decision: "accept", note: null}
|
|
128
|
-
} else if (has_shutoff === 'No'){
|
|
129
|
-
return {decision: "refer", note: null}
|
|
130
|
-
} else {
|
|
131
|
-
return {decision: "reject", note: "Water shutoff must be yes or no"}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
function has_circuit_breaker(has_breaker, year_built){
|
|
136
|
-
if ((has_breaker === 'No') || (year_built >= 1980)){
|
|
137
|
-
return {decision: "accept", note: null}
|
|
138
|
-
} else if(has_breaker === 'Yes'){
|
|
139
|
-
return {decision: "reject", note: "Home built before 1980 cannot have circuit breakers"}
|
|
140
|
-
} else {
|
|
141
|
-
return {decision: "reject", note: "Circuit breaker must be yes or no"}
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
module.exports = {
|
|
146
|
-
is_vacant, under_renovation, plumbing_last_update_year, water_heater_last_update_year,
|
|
147
|
-
electrical_last_update_year, home_heating_last_update_year, heating_source, has_underground_fuel_tank,
|
|
148
|
-
has_steel_braided_hose, has_water_shutoff, has_circuit_breaker
|
|
149
|
-
}
|
|
@@ -1,155 +0,0 @@
|
|
|
1
|
-
function construction_type(type){
|
|
2
|
-
let type_enum = ["Concrete", "Frame", "Log", "Masonry", "Mobile / Manufactured", "Steel", "Modular"]
|
|
3
|
-
if(typeof type != 'string') {
|
|
4
|
-
return {decision: "reject", note: "Construction type must be a string"}
|
|
5
|
-
} else if(!type_enum.includes(type)){
|
|
6
|
-
return {decision: "reject", note: "Construction type must be one of [Concrete, Frame, Log, Masonry, Mobile / Manufactured, Steel, Modular]"}
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
if(["Concrete", "Frame","Masonry", "Steel"].includes(type)){
|
|
10
|
-
return {decision: "accept", note: null}
|
|
11
|
-
} else {
|
|
12
|
-
return {decision: "reject", note: "Construction type not supported"}
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
function siding_material(type){
|
|
17
|
-
let material_enum = ["Adobe", "Aluminum / Steel", "Asbestos", "Brick / Masonry Veneer",
|
|
18
|
-
"Brick / Stone - Solid", "Cement Fiber", "Clapboard", "Exterior Insulation Finishing System (EIFS)", "Log",
|
|
19
|
-
"Stone Veneer", "Stucco", "Vinyl", "Wood", "Other - above descriptions do not apply"]
|
|
20
|
-
if(typeof type != 'string') {
|
|
21
|
-
return {decision: "reject", note: "Siding material must be a string"}
|
|
22
|
-
} else if(!material_enum.includes(type)){
|
|
23
|
-
return {decision: "reject", note: "Siding material must be one of [Adobe, Aluminum / Steel, Asbestos, Brick / Masonry Veneer, Brick / Stone - Solid, Cement Fiber, Clapboard, Exterior Insulation Finishing System (EIFS), Log, Stone Veneer, Stucco, Vinyl, Wood, Other - above descriptions do not apply]"}
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
if(["Log", "Asbestos", "Exterior Insulation Finishing System (EIFS)"].includes(type)){
|
|
27
|
-
return {decision: "reject", note: "Siding material not supported"}
|
|
28
|
-
} else if(type === 'Wood'){
|
|
29
|
-
|
|
30
|
-
} else {
|
|
31
|
-
return {decision: "accept", note: null}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
function protection_class(protection){
|
|
36
|
-
let protection_types = ["1","2","3","4","5","6", "7", "8", "8B", "1Y", "2Y", "3Y", "4Y", "5Y", "6Y", "7Y", "8Y", "9", "1X", "2X", "3X", "4X", "5X", "6X", "7X", "8X", "9", "10", "10W"]
|
|
37
|
-
|
|
38
|
-
if(typeof protection != 'string') {
|
|
39
|
-
return {decision: "reject", note: "Protection class must be a string"}
|
|
40
|
-
} else if(!protection_types.includes(protection)){
|
|
41
|
-
return {decision: "reject", note: `Protection class must be one of ${protection_types}`}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
if(["9", "10"].includes(protection)){
|
|
45
|
-
return {decision: "reject", note: "Protection class not supported"}
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return {decision: "accept", note: null}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function roof_material(material){
|
|
52
|
-
let material_enum = ["Architecture Shingles", "Asphalt Fiberglass Composite", "Clay-Tile-Slate",
|
|
53
|
-
"Concrete Tile", "Corrugated Steel - Metal", "Flat Foam Composite"," Flat Membrane",
|
|
54
|
-
"Flat Tar Gravel", "Other", "Wood Shake", "Wood Shingle"]
|
|
55
|
-
|
|
56
|
-
if(typeof material != 'string') {
|
|
57
|
-
return {decision: "reject", note: "Roof material must be a string"}
|
|
58
|
-
} else if(!material_enum.includes(material)){
|
|
59
|
-
return {decision: "reject", note: `Roof material must be one of ${material_enum}`}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if(["Wood Shake", "Wood Shingle",].includes(material)){
|
|
63
|
-
return {decision: "reject", note: "Roof material not supported"}
|
|
64
|
-
} else {
|
|
65
|
-
return {decision: "accept", note: null}
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
function has_class_a_roof(is_class_a, wildfire_category){
|
|
70
|
-
if(typeof is_class_a != 'string') {
|
|
71
|
-
return {decision: "reject", note: "Has class a roof must be a string"}
|
|
72
|
-
} else if (!["Yes", "No"].includes(is_class_a)){
|
|
73
|
-
return{decision: "reject", note: "Has class a roof must be Yes or No"}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
if(is_class_a === "Yes" || ['A', 'B'].includes(wildfire_category)){
|
|
77
|
-
return {decision: "accept", note: null}
|
|
78
|
-
} else{
|
|
79
|
-
return {decision: "reject", note: "Homes in this wildfire category must have class a roofs"}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
function foundation_type(type){
|
|
84
|
-
let type_enum = ["Basement Finished", "Basement Partially Finished", "Basement Unfinished",
|
|
85
|
-
"Crawlspace", "Other", "Piers", "Pilings", "Stilts", "Slab"]
|
|
86
|
-
if(typeof type != 'string') {
|
|
87
|
-
return {decision: "reject", note: "Foundation type must be a string"}
|
|
88
|
-
} else if(!type_enum.includes(type)){
|
|
89
|
-
return {decision: "reject", note: `Foundation type must be one of ${type_enum}`}
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
if(type == 'Other'){
|
|
93
|
-
return {decision: "refer", note: null}
|
|
94
|
-
} else if(["Piers", "Pilings", "Stilts"].includes(type)){
|
|
95
|
-
return {decision: "reject", note: "Foundation type not supported"}
|
|
96
|
-
} else {
|
|
97
|
-
return {decision: "accept", note: null}
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
function has_slab_foundation_plumbing(has_bad_plumbing){
|
|
104
|
-
if(typeof has_bad_plumbing != 'string') {
|
|
105
|
-
return {decision: "reject", note: "Has slab foundation plumbing must be a string"}
|
|
106
|
-
} else if (!["Yes", "No"].includes(has_bad_plumbing)){
|
|
107
|
-
return{decision: "reject", note: "Has slab foundation plumbing must be Yes or No"}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
if(has_bad_plumbing === "Yes"){
|
|
111
|
-
return {decision: "reject", note: "Homes with slab foundation plumbing are not allowed"}
|
|
112
|
-
} else{
|
|
113
|
-
return {decision: "accept", note: null}
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function fire_protective_devices(devices_list){
|
|
118
|
-
if(!Array.isArray(devices_list)){
|
|
119
|
-
return {decision: "reject", note: "Fire protective devices must be a list"}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
let device_types = ['Local', 'Central', 'Direct', "Sprinkler", "Fire Ext", "Smoke", "No"]
|
|
123
|
-
if(!devices_list.every(device => device_types.includes(device))){
|
|
124
|
-
return {decision: "reject", note: `Unrecognized fire device type. Valid devices: ${device_types}`}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
if(devices_list.includes('Direct') || devices_list.includes('Central')){
|
|
128
|
-
return {decision: "accept", note: null}
|
|
129
|
-
} else {
|
|
130
|
-
return {decision: "reject", note: "Insufficient fire devices"}
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
function theft_protective_devices(devices_list) {
|
|
135
|
-
if(!Array.isArray(devices_list)){
|
|
136
|
-
return {decision: "reject", note: "Theft protective devices must be a list"}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
device_types = ["Dead Bolt", "Local", "Central", "Direct", "24 Hour Security Guard", "No"]
|
|
140
|
-
if(!devices_list.every(device => device_types.includes(device))){
|
|
141
|
-
return {decision: "reject", note: `Unrecognized theft device type. Valid devices: ${device_types}`}
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
if(devices_list.includes('Central') || devices_list.includes('Direct') ||
|
|
145
|
-
devices_list.includes("24 Hour Security Guard")){
|
|
146
|
-
return {decision: "accept", note: null}
|
|
147
|
-
} else {
|
|
148
|
-
return {decision: "reject", note: "Insufficient theft device"}
|
|
149
|
-
}
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
module.exports = {
|
|
153
|
-
construction_type, siding_material, protection_class, roof_material, has_class_a_roof, foundation_type,
|
|
154
|
-
has_slab_foundation_plumbing, fire_protective_devices, theft_protective_devices
|
|
155
|
-
}
|
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
function stand_wf_knockout(mean, arf){
|
|
2
|
-
//Safe checking logic
|
|
3
|
-
if(mean < 0 || arf < 0){
|
|
4
|
-
return {
|
|
5
|
-
category: '',
|
|
6
|
-
underwriter_result: {decision: "reject", note: "Mean and ARF must be positive numbers"}
|
|
7
|
-
}
|
|
8
|
-
}
|
|
9
|
-
if(!Number.isFinite(arf) || !Number.isFinite(mean)){
|
|
10
|
-
return {
|
|
11
|
-
category: '',
|
|
12
|
-
underwriter_result: {decision: "reject", note: "ARF must be a number"}
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
//Main logic
|
|
18
|
-
if(mean >= .7) {
|
|
19
|
-
return {
|
|
20
|
-
category: 'D',
|
|
21
|
-
underwriter_result: {decision: "reject", note: "Stand WF mean must be less than or equal to 0.7"}
|
|
22
|
-
}
|
|
23
|
-
} else if(arf >=8){
|
|
24
|
-
return {
|
|
25
|
-
category: 'C',
|
|
26
|
-
underwriter_result: { decision: "refer", note: null}
|
|
27
|
-
}
|
|
28
|
-
} else if(arf >=5){
|
|
29
|
-
return {
|
|
30
|
-
category: 'C',
|
|
31
|
-
underwriter_result: { decision: "accept", note: null}
|
|
32
|
-
}
|
|
33
|
-
} else if (mean >= .2){
|
|
34
|
-
return {
|
|
35
|
-
category: 'C',
|
|
36
|
-
underwriter_result: { decision: "accept", note: null}
|
|
37
|
-
}
|
|
38
|
-
} else if (mean >= .1){
|
|
39
|
-
return {
|
|
40
|
-
category: 'B',
|
|
41
|
-
underwriter_result: { decision: "accept", note: null}
|
|
42
|
-
}
|
|
43
|
-
} else {
|
|
44
|
-
return {
|
|
45
|
-
category: 'A',
|
|
46
|
-
underwriter_result: { decision: "accept", note: null}
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
function wf_variance(variance){
|
|
52
|
-
if(!Number.isFinite(variance) ) {
|
|
53
|
-
return {decision: "reject", note: "Variance must be a number."}
|
|
54
|
-
} else if(variance < 0){
|
|
55
|
-
return {decision: "reject", note: "Variance must be a positive number."}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
if(variance <= 0.09){
|
|
59
|
-
return {decision: "accept", note: null}
|
|
60
|
-
} else {
|
|
61
|
-
return {decision: "refer", note: null}
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
module.exports = {stand_wf_knockout, wf_variance}
|
package/src/retool_to_socotra.js
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
const {
|
|
2
|
-
knockout, knockout_names, same_address, stand_wf_knockout, has_circuit_breaker, has_class_a_roof,
|
|
3
|
-
check_claims_history
|
|
4
|
-
} = require('./knockouts')
|
|
5
|
-
|
|
6
|
-
function build_policy_from_retool(retool_quote){
|
|
7
|
-
|
|
8
|
-
}
|
|
9
|
-
|
|
10
|
-
function build_quote_change_set(retool_old_quote, retool_new_quote){
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
function convert_quote_from_retool(socotra_quote){
|
|
15
|
-
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
module.exports = {underwrite, knockout_names}
|
|
File without changes
|
|
@@ -1,161 +0,0 @@
|
|
|
1
|
-
const {SocotraEntry, SocotraGroupEntry} = require("./socotra_structure_helper");
|
|
2
|
-
class SocotraPayloadConverter {
|
|
3
|
-
constructor(entries) {
|
|
4
|
-
this.entries = entries
|
|
5
|
-
}
|
|
6
|
-
policy_holder_payload(retool_payload) {
|
|
7
|
-
let missing = []
|
|
8
|
-
let required_fields = ['owner_first_name', 'owner_last_name']
|
|
9
|
-
for (const field of required_fields) {
|
|
10
|
-
if (!retool_payload[field]) {
|
|
11
|
-
missing.push(field)
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
if (missing.length == 0) {
|
|
16
|
-
let values = {
|
|
17
|
-
first_name: retool_payload.owner_first_name,
|
|
18
|
-
last_name: retool_payload.owner_last_name,
|
|
19
|
-
email: retool_payload.owner_email,
|
|
20
|
-
phone_number: retool_payload.owner_phone_number,
|
|
21
|
-
mailing_street_address: retool_payload.mailing_street_address,
|
|
22
|
-
mailing_street_address_2: retool_payload.mailing_street_address2,
|
|
23
|
-
mailing_city: retool_payload.mailing_city,
|
|
24
|
-
mailing_state: retool_payload.mailing_state,
|
|
25
|
-
mailing_zip: retool_payload.mailing_zip,
|
|
26
|
-
ofac_date: retool_payload.ofac_date_pulled,
|
|
27
|
-
ofac_reason: retool_payload.ofac_reason,
|
|
28
|
-
ofac_outcome: retool_payload.ofac_outcome
|
|
29
|
-
}
|
|
30
|
-
return {
|
|
31
|
-
status: 'success',
|
|
32
|
-
error_message: '',
|
|
33
|
-
payload:
|
|
34
|
-
{
|
|
35
|
-
completed: true,
|
|
36
|
-
values: this.stripNoneValues(values, true, true, false)
|
|
37
|
-
}
|
|
38
|
-
}
|
|
39
|
-
} else {
|
|
40
|
-
return {payload: {}, status: 'error', error_message: `must include the following fields [${missing}]`}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
new_policy_payload(retool_payload, policy_holder_locator) {
|
|
45
|
-
let payload = SocotraEntry.socotra_create_policy_template(policy_holder_locator)
|
|
46
|
-
this.entries.forEach(entry => {
|
|
47
|
-
entry.socotra_create_response(retool_payload, payload)
|
|
48
|
-
})
|
|
49
|
-
|
|
50
|
-
let cleaned_payload = this.stripNoneValues(payload, true, true, true)
|
|
51
|
-
return {payload: cleaned_payload, error_message: "", status: "success"}
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
quote_to_retool_payload(socotra_quote) {
|
|
55
|
-
let payload = {}
|
|
56
|
-
this.entries.forEach(entry => {
|
|
57
|
-
entry.retool_response(socotra_quote, payload)
|
|
58
|
-
})
|
|
59
|
-
return {payload: this.stripNoneValues(payload, false, true, false), error_message: "", status: "success"}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
retool_to_quote_updated(retool_payload, old_quote) {
|
|
63
|
-
let old_payload = this.quote_to_retool_payload(old_quote)["payload"]
|
|
64
|
-
|
|
65
|
-
// Pass the original old_quote to the socotra_update method for claims handling
|
|
66
|
-
old_payload._original_quote = old_quote
|
|
67
|
-
|
|
68
|
-
let new_keys = Object.keys(retool_payload)
|
|
69
|
-
new_keys.forEach(key => {
|
|
70
|
-
if (Array.isArray(retool_payload[key])) {
|
|
71
|
-
let new_array = retool_payload[key]
|
|
72
|
-
let old_array = old_payload[key]
|
|
73
|
-
|
|
74
|
-
// Only compare if old_array exists and both are arrays
|
|
75
|
-
if (old_array && Array.isArray(old_array) && JSON.stringify(new_array) === JSON.stringify(old_array)) {
|
|
76
|
-
delete retool_payload[key]
|
|
77
|
-
}
|
|
78
|
-
} else if (typeof retool_payload[key] === 'object' && retool_payload[key] !== null) {
|
|
79
|
-
// Handle nested objects
|
|
80
|
-
if (old_payload[key] && typeof old_payload[key] === 'object') {
|
|
81
|
-
// If the nested objects are the same, remove the key
|
|
82
|
-
if (JSON.stringify(retool_payload[key]) === JSON.stringify(old_payload[key])) {
|
|
83
|
-
delete retool_payload[key]
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
} else if (old_payload[key] === retool_payload[key]) {
|
|
87
|
-
delete retool_payload[key]
|
|
88
|
-
}
|
|
89
|
-
})
|
|
90
|
-
let dwelling_exposure_locator = old_quote.exposures.find(obj => obj.name === 'dwelling')["locator"]
|
|
91
|
-
let payload = SocotraEntry.socotra_create_update_template(dwelling_exposure_locator)
|
|
92
|
-
this.entries.forEach(entry => {
|
|
93
|
-
// Check if the entry's retool_id is in the retool_payload keys
|
|
94
|
-
// For nested keys (e.g., "additional_insured_data.additionalInterest"), check if the parent key exists
|
|
95
|
-
const retool_id_parts = entry.retool_id ? entry.retool_id.split('.') : [];
|
|
96
|
-
const parent_key = retool_id_parts[0];
|
|
97
|
-
|
|
98
|
-
// Special handling for has_any_claim_history field which depends on claims_data
|
|
99
|
-
if (entry.socotra_id === 'has_any_claim_history' && retool_payload.claims_data) {
|
|
100
|
-
entry.socotra_update(retool_payload, payload);
|
|
101
|
-
} else if (Object.keys(retool_payload).includes(entry.retool_id) ||
|
|
102
|
-
(parent_key && Object.keys(retool_payload).includes(parent_key))) {
|
|
103
|
-
if(entry instanceof SocotraGroupEntry){
|
|
104
|
-
entry.socotra_update(retool_payload, payload, old_payload)
|
|
105
|
-
} else{
|
|
106
|
-
entry.socotra_update(retool_payload, payload)
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
})
|
|
110
|
-
|
|
111
|
-
payload = this.stripNoneValues(payload, true, true, false)
|
|
112
|
-
if (Object.keys(payload.updateExposures[0].fieldValues).length === 0) {
|
|
113
|
-
delete payload["updateExposures"]
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
if (Object.keys(payload.fieldValues).length === 0) {
|
|
117
|
-
delete payload["fieldValues"]
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
return {payload: payload, error_message: "", status: "success"}
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
stripNoneValues(payload, nulls, undefineds, nans) {
|
|
124
|
-
if (nulls) {
|
|
125
|
-
payload = this.stripNulls(payload, x => x == null)
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
if (undefineds) {
|
|
129
|
-
payload = this.stripNulls(payload, x => x === undefined)
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
if (nans) {
|
|
133
|
-
payload = this.stripNulls(payload, x => Number.isNaN(x))
|
|
134
|
-
}
|
|
135
|
-
return payload
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
//Socotra Doesn't like nulls, so we have to strip them
|
|
139
|
-
|
|
140
|
-
stripNulls(payload, filter_func) {
|
|
141
|
-
let strip_with_args = x => this.stripNulls(x, filter_func)
|
|
142
|
-
|
|
143
|
-
if (Array.isArray(payload)) {
|
|
144
|
-
// If it's an array, recursively process each item and filter out nulls
|
|
145
|
-
return payload
|
|
146
|
-
.map(strip_with_args)
|
|
147
|
-
.filter(item => !filter_func(item));
|
|
148
|
-
} else if (typeof payload === 'object' && payload !== null) {
|
|
149
|
-
// If it's an object, recursively process each key-value pair
|
|
150
|
-
return Object.fromEntries(
|
|
151
|
-
Object.entries(payload)
|
|
152
|
-
.map(([key, value]) => [key, strip_with_args(value)]) // Recursively call for each value
|
|
153
|
-
.filter(([_, value]) => !filter_func(value)) // Filter out null values
|
|
154
|
-
);
|
|
155
|
-
}
|
|
156
|
-
// Return the value itself if it's not an object or array
|
|
157
|
-
return payload;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
module.exports = {SocotraPayloadConverter}
|