Class: Formulary::PayerInsurancePlanFactory

Inherits:
Object
  • Object
show all
Defined in:
lib/formulary/payer_insurance_plan_factory.rb

Overview

Class to build PayerInsurancePlan resources from a QHPPlan

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(plan) ⇒ PayerInsurancePlanFactory

Returns a new instance of PayerInsurancePlanFactory.



11
12
13
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 11

def initialize(plan)
  @plan = plan
end

Instance Attribute Details

#planObject (readonly)

Returns the value of attribute plan.



9
10
11
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 9

def plan
  @plan
end

Instance Method Details

#benefit_tier(tier, pharmacy_type) ⇒ Object (private)

Benefit per tier in a given pharmacy type



362
363
364
365
366
367
368
369
370
371
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 362

def benefit_tier(tier, pharmacy_type)
  current_cost = nil
  tier.cost_sharing.each do |cost|
    if cost.pharmacy_type != pharmacy_type
      current_cost = cost
    end
  end

  benefit_tier_cost(tier, current_cost)
end

#benefit_tier_cost(tier, cost) ⇒ Object (private)

Cost sharing benefit of a given tier



374
375
376
377
378
379
380
381
382
383
384
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 374

def benefit_tier_cost(tier, cost)
  return if tier.nil? || cost.nil?

  {
    type: specific_cost_category(tier.name),
    cost: [
      copay_cost(cost),
      coinsurance_cost(cost),
    ],
  }
end

#benefits(pharmacy_type) ⇒ Object (private)

Returns cost benefits [Array] per tier and pharmacy_type.

Returns:

  • cost benefits [Array] per tier and pharmacy_type



357
358
359
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 357

def benefits(pharmacy_type)
  plan.tiers.map { |tier| benefit_tier(QHPDrugTier.new(tier), pharmacy_type) }
end

#buildObject



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 15

def build
  name.strip!

  FHIR::InsurancePlan.new(
    id: PAYER_PLAN_ID_PREFIX + plan.id,
    meta: meta,
    text: text,
    identifier: identifier,
    status: "active",
    name: name,
    type: type,
    period: period,
    coverageArea: coverageArea,
    contact: contact,
    coverage: coverage,
    plan: plans,
  )
end

#coinsurance_cost(cost) ⇒ Object (private)



416
417
418
419
420
421
422
423
424
425
426
427
428
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 416

def coinsurance_cost(cost)
  return if cost.nil?
  {
    type: cost_type("coinsurance"),
    qualifiers: coinsurance_option(cost.coinsurance_option),
    value: {
      value: cost.coinsurance_rate * 100,
      system: UCUM_SYSTEM,
      code: "%",

    },
  }
end

#coinsurance_option(option) ⇒ Object (private)



454
455
456
457
458
459
460
461
462
463
464
465
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 454

def coinsurance_option(option)
  return if option.nil?
  {
    coding: [
      {
        system: COST_SHARE_SYSTEM,
        code: option.downcase,
        display: COST_SHARE_OPTION_DISPLAY[option.downcase],
      },
    ],
  }
end

#contactObject (private)



111
112
113
114
115
116
117
118
119
120
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 111

def contact
  contact_list = [
    marketing_contact,
    summary_contact,
    formulary_contact,
    email_contact,
  ].compact

  return contact_list if !contact_list.empty?
end

#copay_cost(cost) ⇒ Object (private)

Returns copay details.

Returns:

  • copay details



402
403
404
405
406
407
408
409
410
411
412
413
414
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 402

def copay_cost(cost)
  return if cost.nil?
  {
    type: cost_type("copay"),
    qualifiers: copay_option(cost.copay_option),
    value: {
      value: cost.copay_amount,
      unit: "$",
      system: COPAY_AMOUNT_SYSTEM,
      code: COPAY_AMOUNT_CODE,
    },
  }
end

#copay_option(option) ⇒ Object (private)



441
442
443
444
445
446
447
448
449
450
451
452
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 441

def copay_option(option)
  return if option.nil?
  {
    coding: [
      {
        system: COST_SHARE_SYSTEM,
        code: option.downcase,
        display: COST_SHARE_OPTION_DISPLAY[option.downcase],
      },
    ],
  }
end

#cost_type(value) ⇒ Object (private)



430
431
432
433
434
435
436
437
438
439
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 430

def cost_type(value)
  {
    coding: [
      {
        system: BENEFIT_COST_TYPE_SYSTEM,
        code: value,
      },
    ],
  }
end

#coverageObject (private)



233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 233

def coverage
  [
    {
      extension: extension,
      type: coverage_type,
      benefit: [
        {
          type: {
            coding: [
              {
                system: PLAN_TYPE_SYSTEM,
                code: "drug",
              },
            ],
          },
        },
      ],
    },
  ]
end

#coverage_typeObject (private)



254
255
256
257
258
259
260
261
262
263
264
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 254

def coverage_type
  {
    coding: [
      {
        system: FORMULARY_TYPE_SYSTEM,
        code: FORMULARY_TYPE_CS_CODE,
        display: FORMULARY_TYPE_CS_DISPLAY,
      },
    ],
  }
end

#coverageAreaObject (private)



102
103
104
105
106
107
108
109
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 102

def coverageArea
  choice = ["Location/StateOfCTLocation", "Location/UnitedStatesLocation"]
  [
    {
      "reference": choice.sample,
    },
  ]
end

#email_contactObject (private)



209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 209

def email_contact
  value = plan.email_contact
  return if value.nil?

  {

    purpose: {
      coding: [
        {
          system: CONTACT_ENTITY_SYSTEM,
          code: CONTACT_PATINF_CODE,
          display: CONTACT_PATINF_DISPLAY,
        },
      ],
    },
    telecom: [
      {
        system: "email",
        value: value,
      },
    ],
  }
end

#extensionObject (private)



266
267
268
269
270
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 266

def extension
  [
    formulary_extension,
  ].flatten.compact
end

#formulary_contactObject (private)



180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 180

def formulary_contact
  value = plan.formulary_url
  return if value.nil?

  {

    purpose: {
      coding: [
        {
          system: CONTACT_ENTITY_SYSTEM,
          code: CONTACT_PATINF_CODE,
          display: CONTACT_PATINF_DISPLAY,
        },
        {
          system: PLAN_CONTACT_TYPE_CS,
          code: CONTACT_FORMULARY_CODE,
          display: CONTACT_FORMULARY_DISPLAY,
        },
      ],
    },
    telecom: [
      {
        system: "url",
        value: value,
      },
    ],
  }
end

#formulary_extensionObject (private)



272
273
274
275
276
277
278
279
280
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 272

def formulary_extension
  {
    url: FORMULARY_REFERENCE_EXTENSION,
    valueReference: {
      reference: "InsurancePlan/" + FORMULARY_ID_PREFIX + plan.id,
      type: "InsurancePlan",
    },
  }
end

#identifierObject (private)



50
51
52
53
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 50

def identifier
  # TODO: Is this really an identifier?
  [{ value: PAYER_PLAN_ID_PREFIX + plan.id }]
end

#marketing_contactObject (private)



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 122

def marketing_contact
  value = plan.marketing_url
  return if value.nil?

  {

    purpose: {
      coding: [
        {
          system: CONTACT_ENTITY_SYSTEM,
          code: CONTACT_PATINF_CODE,
          display: CONTACT_PATINF_DISPLAY,
        },
        {
          system: PLAN_CONTACT_TYPE_CS,
          code: CONTACT_MARKETING_CODE,
          display: CONTACT_MARKETING_DISPLAY,
        },
      ],
    },
    telecom: [
      {
        system: "url",
        value: value,
      },
    ],
  }
end

#metaObject (private)



36
37
38
39
40
41
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 36

def meta
  {
    profile: [PAYER_INSURANCE_PLAN_PROFILE],
    lastUpdated: plan.last_updated + "T00:00:00Z",
  }
end

#nameObject (private)



55
56
57
58
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 55

def name
  names = plan.marketing_name.split(/\W+/)
  "#{names[0]} #{names[1]}"
end

#network_reference(value) ⇒ Object (private)



312
313
314
315
316
317
318
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 312

def network_reference(value)
  return if value.nil?

  {
    display: value,
  }
end

#networksObject (private)

Returns a list of networks [Array] or nil if no networks.

Returns:

  • a list of networks [Array] or nil if no networks



305
306
307
308
309
310
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 305

def networks
  networks = plan.network
  return if networks.nil? || networks.empty?

  networks.map { |network| network_reference(network) }
end

#periodObject (private)



94
95
96
97
98
99
100
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 94

def period
  current_year = Date.today.year
  {
    "start": "#{current_year}-01-01",
    "end": "#{current_year}-12-31",
  }
end

#pharmacy_network_type(pharmacy_type) ⇒ Object (private)



344
345
346
347
348
349
350
351
352
353
354
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 344

def pharmacy_network_type(pharmacy_type)
  {
    coding: [
      {
        system: PHARMACY_TYPE_SYSTEM,
        code: pharmacy_type,
        display: PHARMACY_TYPE_DISPLAY[pharmacy_type],
      },
    ],
  }
end

#plan_typeObject (private)



292
293
294
295
296
297
298
299
300
301
302
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 292

def plan_type
  {
    coding: [
      {
        system: PLAN_TYPE_SYSTEM,
        code: PLAN_TYPE_CODE,
        display: PLAN_TYPE_DISPLAY,
      },
    ],
  }
end

#plansObject (private)



282
283
284
285
286
287
288
289
290
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 282

def plans
  [
    {
      type: plan_type,
      network: networks,
      specificCost: specific_costs,
    },
  ]
end

#specific_cost(pharmacy_type) ⇒ Object (private)

Constructs a specific drug cost per pharmacy type



337
338
339
340
341
342
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 337

def specific_cost(pharmacy_type)
  {
    category: pharmacy_network_type(pharmacy_type),
    benefit: benefits(pharmacy_type),
  }
end

#specific_cost_category(value) ⇒ Object (private)

Returns the tier category details.

Returns:

  • the tier category details



387
388
389
390
391
392
393
394
395
396
397
398
399
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 387

def specific_cost_category(value)
  return if value.nil?

  {
    coding: [
      {
        system: DRUG_TIER_SYSTEM,
        code: value.downcase,
        display: DRUG_TIER_DISPLAY[value.downcase],
      },
    ],
  }
end

#specific_costsObject (private)

Constructs the list of cost sharing info per pharmacy type.



321
322
323
324
325
326
327
328
329
330
331
332
333
334
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 321

def specific_costs
  pharmacy_list = Array.new
  # Put all pharmacy types into an array
  plan.tiers.each do |tier|
    qhp_drug = QHPDrugTier.new(tier)
    qhp_drug.cost_sharing.each do |cost_sharing|
      if (!pharmacy_list.include?(cost_sharing.pharmacy_type))
        pharmacy_list.push(cost_sharing.pharmacy_type)
      end
    end
  end

  pharmacy_list.map { |pharmacy_type| specific_cost(pharmacy_type) }
end

#summary_contactObject (private)



151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 151

def summary_contact
  value = plan.summary_url
  return if value.nil?

  {

    purpose: {
      coding: [
        {
          system: CONTACT_ENTITY_SYSTEM,
          code: CONTACT_PATINF_CODE,
          display: CONTACT_PATINF_DISPLAY,
        },
        {
          system: PLAN_CONTACT_TYPE_CS,
          code: CONTACT_SUMMARY_CODE,
          display: CONTACT_SUMMARY_DISPLAY,
        },
      ],
    },
    telecom: [
      {
        system: "url",
        value: value,
      },
    ],
  }
end

#textObject (private)



43
44
45
46
47
48
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 43

def text
  {
    status: "generated",
    div: %(<div xmlns="http://www.w3.org/1999/xhtml">#{name}</div>),
  }
end

#typeObject (private)



60
61
62
63
64
65
66
67
68
69
70
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 60

def type
  {
    coding: [
      {
        system: INSURANCE_PRODUCT_TYPE_SYSTEM,
        code: type_code,
        display: type_display,
      },
    ],
  }
end

#type_codeObject (private)

Loosely mapping to provide examples of different types



73
74
75
76
77
78
79
80
81
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 73

def type_code
  if plan.marketing_name.include? " PPO "
    return "commppo"
  elsif plan.marketing_name.include? " HMO "
    return "commhmo"
  else
    return "mediadv"
  end
end

#type_displayObject (private)

Loosely mapping to provide examples of different types



84
85
86
87
88
89
90
91
92
# File 'lib/formulary/payer_insurance_plan_factory.rb', line 84

def type_display
  if plan.marketing_name.include? " PPO "
    return "Commercial PPO"
  elsif plan.marketing_name.include? " HMO "
    return "Commercial HMO"
  else
    return "Medicare Advantage"
  end
end