automation and view updates

This commit is contained in:
Jason Jordan
2026-04-17 15:35:10 -04:00
parent 247a075c9c
commit 7ab1143db8
30 changed files with 124704 additions and 602 deletions
+6 -1
View File
@@ -2,7 +2,12 @@ class EmployersController < ApplicationController
# View Methods
def index
@employers = Employer.all
@not_automation_ready = Employer.not_automation_ready
@missing_keychain_initialization = Employer.missing_keychain_initialization
@missing_plans_initialization = Employer.missing_plans_initialization
@missing_members_initialization = Employer.missing_members_initialization
@active_with_active_id_card_setup = Employer.active_with_active_id_card_setup
@deactivated = Employer.deactivated
end
def show
+8 -3
View File
@@ -24,9 +24,14 @@ module IdCard
# API Methods
def get_plan_benefits
@plan_benefits = IdCard::Plan.find(params[:id]).plan_benefits
render json: @plan_benefits.as_json
def get_plan_template
@template_plan = IdCard::Plan.includes(:plan_benefits).find_by(id: params[:id], template: true)
render json: @template_plan.as_json(
only: [:title],
include: {
plan_benefits: { except: [:id, :plan_id, :created_at, :updated_at] }
}
)
end
private
@@ -87,6 +87,17 @@ module IdCard
end
def update_active_status
@setup.active = !@setup.active
if @setup.save
puts "sucess"
redirect_to employer_path(@setup.employer.slug), notice: 'ID Card Active Status successfully updated.'
else
puts "fail"
render :show, status: :unprocessable_entity
end
end
def destroy
# @resource = Resource.find(params[:id])
# @resource.destroy
@@ -2,7 +2,7 @@ import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
static values = { url: String };
static targets = ["benefit"];
static targets = ["benefit", "title"];
connect() {
}
@@ -14,19 +14,21 @@ export default class extends Controller {
return;
}
const url = `/id_card/plans/${templateId}/get_plan_benefits`
const url = `/id_card/plans/${templateId}/get_plan_template`
const response = await fetch(url);
const templateBenefitsData = await response.json();
const templatePlanData = await response.json();
this.#updateFields(templateBenefitsData)
this.#updateFields(templatePlanData)
}
clearFields() {
}
async #updateFields(templateBenefitsData) {
async #updateFields(templatePlanData) {
const titleElement = this.titleTarget
titleElement.value = templatePlanData.title.match(/^(.*\d)k(?=\d)/i)[0].replace(/(\d)/, ' $1')
const benefitTargetsList = this.benefitTargets
templateBenefitsData.forEach(function(bene) {
templatePlanData.plan_benefits.forEach(function(bene) {
const targetElement = benefitTargetsList.find(
(element) => element.dataset.sequence == bene.sequence
);
+111 -100
View File
@@ -1,112 +1,123 @@
class UpdateEmployerJob < ApplicationJob
queue_as :default
def perform(pl_plan_key, plan_header = {}, full_sync = false)
def perform(employer_identifier: {}, employer_plan_header: {}, full_sync: false)
unless plan_header.present?
sql_query = "SELECT PLPlanKey, PlanId, ShortDesc FROM PLPlanHeader WHERE PLPlanKey = #{pl_plan_key}"
plan_header = VhcsRecord.connection.select_all(sql_query).first
if employer_plan_header.present?
pl_plan_key = employer_plan_header['PLPlanKey'].to_s
elsif employer_identifier[:group_number]
group_number = employer_identifier[:group_number]
pl_plan_key = Vhcs::PlPlanGroupCode.find_by(group_code: group_number).pl_plan_key
elsif employer_identifier[:pl_plan_key]
pl_plan_key = employer_identifier[:pl_plan_key]
end
puts "== Updating #{plan_header['ShortDesc'].strip.titleize} =="
if pl_plan_key.present?
plan_code = Vhcs::HlPlanCode.find_by(plan_key: plan_header['PLPlanKey'])
pb_company_plan = Vhcs::PbCompanyPlans.find_by(pl_plan_key: plan_header['PLPlanKey'])
employer = Employer.find_or_create_by!(pl_plan_key: plan_header['PLPlanKey'])
full_sync = employer.previously_new_record? || full_sync
# id_card_setup = employer.id_card_setup || employer.create_id_card_setup(pl_plan_key: employer.pl_plan_key)
# id_card_setup = employer.id_card_setup.find_or_create_by(pl_plan_key: employer.pl_plan_key)
employer_update_attrs = {}
setup_update_attrs = {}
employer_update_attrs.merge!({
plan_id: plan_header['PlanId'].strip.to_i,
company_pb_entity_key: pb_company_plan.company_pb_entity_key
})
if plan_code.present?
employer_update_attrs.merge!({
group_number: plan_code.group_number,
effective_date: plan_code.effect_date.strftime("%m/%d/%Y")
})
setup_update_attrs.merge!({
rx_group_number: plan_code.medical_number
})
end
# id_card_setup = employer.id_card_setup.find_or_create_by(pl_plan_key: employer.pl_plan_key)
# employer.name = plan_header['ShortDesc'].strip.titleize
# employer.plan_id = plan_header['PlanId'].strip.to_i
# id_card_templates = determine_id_card_templates(employer.pl_plan_key)
# employer.single_card_template = id_card_templates[:single_card_template]
# employer.multiple_card_template = id_card_templates[:multiple_card_template]
if full_sync
employer_update_attrs.merge!({
name: plan_header['ShortDesc'].strip.titleize
})
setup_update_attrs.merge!({
print_name: determine_card_print_name(pb_company_plan.company_pb_entity_key, @pl_plan_key)
})
end
employer.update(employer_update_attrs)
# if full_sync
# setup_update_attrs.merge!{
# print_name: card_print_name
# }
# end
id_card_setup = employer.id_card_setup || employer.create_id_card_setup!(pl_plan_key: employer.pl_plan_key)
id_card_setup.update(setup_update_attrs)
# plan_code = Vhcs::HlPlanCode.find_by(plan_key: employer.pl_plan_key)
# employer.group_number = plan_code.group_number
# id_card_setup.rx_group_number = plan_code.medical_number
# employer.effective_date = plan_code.effect_date.strftime("%m/%d/%Y")
# pb_company_plan = Vhcs::PbCompanyPlans.find_by(pl_plan_key: employer.pl_plan_key)
# employer.company_pb_entity_key = pb_company_plan.company_pb_entity_key
# card_print_name = Vhcs::PbEntity.where(company_pb_entity_key: employer.company_pb_entity_key, entity_type_id: 1007).last.last_name
# id_card_setup.print_name = card_print_name
# if employer.up_to_date?
# employer.active = true
# end
# employer.default_network_logo = determine_network_logos(employer.pl_plan_key)
# plan_codes = Vhcs::HlEgglestonCardBenefit.where(plan_key: employer.pl_plan_key).pluck(:plan_id).uniq
employer_plans = employer.id_card_setup.plans
plan_titles = employer_plans.pluck(:title)
vhcs_plans = Vhcs::PbProduct.where(company_pb_entity_key: pb_company_plan.company_pb_entity_key, is_active: 255)
vhcs_plans.each do |vp|
if employer_plans.present? && plan_titles.all?(&:present?) && employer_plans.find_by(pb_product_key: vp.pb_product_key).nil?
plan_title_matcher = Amatch::JaroWinkler.new(vp.short_description)
closest_title = plan_titles.max_by { |title| plan_title_matcher.match(title) }
plan = employer_plans.find_or_create_by(title: closest_title)
plan.update(
title: vp.short_description,
pb_product_key: vp.pb_product_key,
pl_plan_key: employer.pl_plan_key
)
plan_titles.delete(closest_title)
elsif employer_plans.blank?
employer_plans.create!(
pb_product_key: vp.pb_product_key,
title: vp.short_description,
pl_plan_key: employer.pl_plan_key
)
# plan.update(
# title: vp.short_description,
# pl_plan_key: employer.pl_plan_key
# )
if employer_plan_header.empty?
sql_query = "SELECT PLPlanKey, PlanId, ShortDesc FROM PLPlanHeader WHERE PLPlanKey = #{pl_plan_key}"
employer_plan_header = VhcsRecord.connection.select_all(sql_query).first
end
end
employer
puts "== Updating #{employer_plan_header['ShortDesc'].strip.titleize} =="
plan_code = Vhcs::HlPlanCode.find_by(plan_key: pl_plan_key)
pb_company_plan = Vhcs::PbCompanyPlans.find_by(pl_plan_key: pl_plan_key)
employer = Employer.find_or_create_by!(employer_identifier)
id_card_setup = employer.id_card_setup || employer.create_id_card_setup!(pl_plan_key: employer.pl_plan_key)
full_sync = employer.previously_new_record? || full_sync
unless group_number.present?
group_number = Vhcs::PlPlanGroupCode.find_by(pl_plan_key: pl_plan_key).group_code
end
employer_update_attrs = {}
employer_update_attrs.merge!({
plan_id: employer_plan_header['PlanId'].strip.to_i,
company_pb_entity_key: pb_company_plan.company_pb_entity_key,
group_number: group_number,
pl_plan_key: pl_plan_key
})
if plan_code.present? && employer.effective_date.blank?
employer_update_attrs.merge!({
effective_date: plan_code.effect_date.strftime("%m/%d/%Y")
})
end
if full_sync && employer.name.blank?
employer_update_attrs.merge!({
name: employer_plan_header['ShortDesc'].strip.titleize
})
end
employer.update(employer_update_attrs)
if [employer.pl_plan_key, employer.group_number, employer.company_pb_entity_key, employer.plan_id].all?(&:present?)
employer.update(active: true)
end
setup_update_attrs = {}
if plan_code.present? && id_card_setup.rx_group_number.blank?
setup_update_attrs.merge!({
rx_group_number: plan_code.medical_number
})
end
if full_sync
setup_update_attrs.merge!({
print_name: determine_card_print_name(pb_company_plan.company_pb_entity_key, pl_plan_key)
})
end
id_card_setup.update(setup_update_attrs)
# plan_code = Vhcs::HlPlanCode.find_by(plan_key: employer.pl_plan_key)
# employer.group_number = plan_code.group_number
# id_card_setup.rx_group_number = plan_code.medical_number
# employer.effective_date = plan_code.effect_date.strftime("%m/%d/%Y")
# pb_company_plan = Vhcs::PbCompanyPlans.find_by(pl_plan_key: employer.pl_plan_key)
# employer.company_pb_entity_key = pb_company_plan.company_pb_entity_key
# card_print_name = Vhcs::PbEntity.where(company_pb_entity_key: employer.company_pb_entity_key, entity_type_id: 1007).last.last_name
# id_card_setup.print_name = card_print_name
# if employer.up_to_date?
# employer.active = true
# end
# employer.default_network_logo = determine_network_logos(employer.pl_plan_key)
# plan_codes = Vhcs::HlEgglestonCardBenefit.where(plan_key: employer.pl_plan_key).pluck(:plan_id).uniq
# employer_plans = employer.id_card_setup.plans
# plan_titles = employer_plans.pluck(:title)
# vhcs_plans = Vhcs::PbProduct.where(company_pb_entity_key: pb_company_plan.company_pb_entity_key, is_active: 255)
# vhcs_plans.each do |vp|
# if employer_plans.present? && plan_titles.all?(&:present?) && employer_plans.find_by(pb_product_key: vp.pb_product_key).nil?
# plan_title_matcher = Amatch::JaroWinkler.new(vp.short_description)
# closest_title = plan_titles.max_by { |title| plan_title_matcher.match(title) }
# plan = employer_plans.find_or_create_by(title: closest_title)
# plan.update(
# title: vp.short_description,
# pb_product_key: vp.pb_product_key,
# pl_plan_key: employer.pl_plan_key
# )
# plan_titles.delete(closest_title)
# elsif employer_plans.blank?
# employer_plans.create!(
# pb_product_key: vp.pb_product_key,
# title: vp.short_description,
# pl_plan_key: employer.pl_plan_key
# )
# # plan.update(
# # title: vp.short_description,
# # pl_plan_key: employer.pl_plan_key
# # )
# end
# end
end
employer.presence
end
private
+67
View File
@@ -0,0 +1,67 @@
class UpdateEmployerPlansJob < ApplicationJob
queue_as :default
def perform(pl_plan_key)
employer = Employer.includes(:id_card_setup).find_by(pl_plan_key: pl_plan_key)
setup = employer.id_card_setup
puts "== Updating #{employer.name} Plans =="
pb_company_plan = Vhcs::PbCompanyPlans.find_by(pl_plan_key: pl_plan_key)
vhcs_card_plans = Vhcs::PbProduct.where(company_pb_entity_key: pb_company_plan.company_pb_entity_key, is_active: 255).where.not("ShortDescription LIKE ?", "%Vision%")
unless setup.has_dental
vhcs_card_plans = vhcs_card_plans.where.not("ShortDescription LIKE ?", "%Dental%")
end
vhcs_card_plan_product_keys = vhcs_card_plans.pluck(:pb_product_key)
vhcs_card_plan_titles = vhcs_card_plans.pluck(:short_description).map(&:strip)
employer_plans = employer.id_card_setup.plans
employer_plan_product_keys = employer_plans.pluck(:pb_product_key)
employer_plan_titles = employer_plans.pluck(:title)
plans_without_product_key = employer_plans.where(pb_product_key: ["", nil])
new_card_plan_pb_product_keys = vhcs_card_plan_product_keys - employer_plan_product_keys
vhcs_card_plans_to_import = Vhcs::PbProduct.where(pb_product_key: new_card_plan_pb_product_keys)
vhcs_card_plans_to_import.each do |vhcs_plan_import|
# if employer_plans.present? && plan_titles.all?(&:present?) && employer_plans.find_by(pb_product_key: vhcs_plan.pb_product_key).nil?
# if employer_plans.find_by(pb_product_key: vhcs_plan.pb_product_key).nil?
if plans_without_product_key
plan_title_matcher = Amatch::JaroWinkler.new(vhcs_plan_import.short_description.strip)
title_match = employer_plan_titles.max_by { |title| plan_title_matcher.match(title) }
plan = employer_plans.find_or_create_by(title: title_match)
plan.update(
pb_product_key: vhcs_plan_import.pb_product_key,
title: vhcs_plan_import.short_description.strip,
pl_plan_key: employer.pl_plan_key
)
employer_plan_titles.delete(title_match)
else
employer_plans.create!(
pb_product_key: vhcs_plan_import.pb_product_key,
title: vhcs_plan_import.short_description.strip,
pl_plan_key: employer.pl_plan_key
)
end
end
employer
end
private
def determine_card_print_name(company_pb_entity_key, pl_plan_key)
card_print_names = Vhcs::PbEntity.where(company_pb_entity_key: company_pb_entity_key, entity_type_id: 1007)
.where.not("LastName LIKE ? OR LastName LIKE ? OR LastName LIKE ?", "%COBRA%", "Active", ".%").pluck(:last_name)
if pl_plan_key == "2"
"sm ART"
elsif card_print_names.count > 2
Employer.employer_trim_name(card_print_names.first)
else
card_print_names.last
end
end
end
+6 -6
View File
@@ -3,11 +3,11 @@ class UpdateMemberJob < ApplicationJob
def perform(pb_entity_key, employer_id, has_divisions = false, has_dental = false, vw_mb_member = {})
unless vw_mb_member.present?
vw_mb_member = Vhcs::VwmbMember.find_by(enrollee_type_value_id: 1, pb_entity_key: pb_entity_key).attributes.with_indifferent_access.slice(:mb_member_key, :pb_entity_key, :pl_plan_key, :family_id, :full_name_last_name_first, :social_security_number)
end
unless vw_mb_member.present?
vw_mb_member = Vhcs::VwmbMember.find_by(enrollee_type_value_id: 1, pb_entity_key: pb_entity_key).attributes.with_indifferent_access.slice(:mb_member_key, :pb_entity_key, :pl_plan_key, :family_id, :full_name_last_name_first, :social_security_number)
end
pb_products = Vhcs::PbProduct.joins('
pb_products = Vhcs::PbProduct.joins('
INNER JOIN "PBProductAvailability" ON "PBProductAvailability"."PBProductKey" = "PBProduct"."PBProductKey"
INNER JOIN "PBProductParticipation" ON "PBProductParticipation"."PBProductAvailabilityKey" = "PBProductAvailability"."PBProductAvailabilityKey"
INNER JOIN "PBCoveredEntities" ON "PBProductParticipation"."PBProductParticipationKey" = "PBCoveredEntities"."PBProductParticipationKey"
@@ -42,7 +42,7 @@ class UpdateMemberJob < ApplicationJob
end
if has_dental
medical_pb_product_key = pb_products.where(short_description: "Medical")&.first&.pb_product_key
medical_pb_product_key = pb_products.where("ShortDescription LIKE ?", "%Medical%")&.first&.pb_product_key
dental_pb_product_key = pb_products.where("ShortDescription LIKE ?", "%Dental%")&.first&.pb_product_key
# dental_pb_product_key = pb_products.where(short_description: "Dental")&.first&.pb_product_key
if dental_pb_product_key
@@ -74,8 +74,8 @@ class UpdateMemberJob < ApplicationJob
# else
# end
puts "---- #{member.name}"
end
puts "---- #{member.name}"
member.presence
end
+92 -20
View File
@@ -2,34 +2,96 @@ module EmployerAutomation
extend ActiveSupport::Concern
included do
scope :new_groups, -> {
where(active: false)
.where.not(pl_plan_key: [nil, ''])
scope :not_automation_ready, -> {
where(pl_plan_key: [nil, ''], group_number: [nil, ''])
}
scope :with_plans, -> {
joins(id_card_setup: :plans).distinct
scope :automation_ready, -> {
where.not(pl_plan_key: [nil, ''])
.or(where.not(group_number: [nil, '']))
}
scope :missing_keychain_values, -> {
where(company_pb_entity_key: [nil, ''])
.or(where(plan_id: [nil, '']))
.or(where(group_number: [nil, '']))
.or(where(pl_plan_key: [nil, '']))
}
scope :missing_keychain_initialization, -> {
inactive.automation_ready.missing_keychain_values
}
scope :building_id_card_setup, -> {
active.left_outer_joins(:id_card_setup)
.where(id_card_setup: {active: false})
}
scope :missing_plans_initialization, -> {
building_id_card_setup
.where.missing(:plans)
.or(
where(
id: joins(:plans)
.where(plans: { pb_product_key: [nil, ''] })
.select(:id)
)
)
}
scope :missing_members_initialization, -> {
building_id_card_setup
.where.associated(:plans)
.where.not(
id: joins(:plans)
.where(plans: { pb_product_key: [nil, ''] })
.select(:id)
).distinct
}
scope :active_with_active_id_card_setup, -> {
active.left_outer_joins(:id_card_setup)
.where(id_card_setup: {active: true})
}
scope :with_keychain_values, -> {
where.not(
pl_plan_key: [nil, ''],
group_number: [nil, ''],
company_pb_entity_key: [nil, ''],
plan_id: [nil, '']
)
}
scope :deactivated, -> {
inactive.with_keychain_values
}
# Employer.joins(:id_card_setup)
# .left_outer_joins(:plans)
# .where(plans: { pb_product_key: [nil, ''] })
# .group('users.id') # Group by user ID
# .having('COUNT(posts.id) = 0')
# Employer.left_outer_joins(:plans)
# .where(plans: { id: nil })
# .or(Employer.where(plans: { pb_product_key: [nil, ''] }))
# Employer.where.missing(:plans)
# .or(Employer.joins(:plans).where(plans: { pb_product_key: [nil, ''] }))
# Employer.joins(id_card_setup: :plans).where.not("plans.id_card_setup_id = id_card_setup.id").or
# (where(plans: { pb_product_key: [nil, ''] }))
# scope :with_survey_and_no_questions, -> {
# joins(:survey) # join has_one
# .left_joins(survey: :questions) # join has_many through has_one
# .where(questions: { id: nil }) # filter where has_many is empty
# }
scope :missing_keychain_values, -> {
new_groups
.where(
arel_table[:company_pb_entity_key].in([nil, ''])
.or(arel_table[:plan_id].in([nil, '']))
.or(arel_table[:group_number].in([nil, '']))
.or(arel_table[:effective_date].in([nil, '']))
)
}
scope :missing_initial_members, -> {
new_groups.with_plans
}
# scope :missing_initial_members, -> {
# new_groups.with_plans
# }
end
# class_methods do
@@ -49,11 +111,21 @@ module EmployerAutomation
# end
def sync_members_with_vhcs
AutomationService::EmployerMembersUpdate.new(self.pl_plan_key).call
AutomationService::EmployerMembersUpdate.new(pl_plan_key).call
end
def sync_plans_with_vhcs
AutomationService::EmployerPlansUpdate.new(pl_plan_key).call
end
def automation_identifier
attributes.with_indifferent_access.slice(
pl_plan_key.present? ? :pl_plan_key : :group_number
)
end
def sync_with_vhcs
AutomationService::EmployerUpdate.new(self.pl_plan_key).call
employer_identifier = automation_identifier
AutomationService::EmployerUpdate.new(employer_identifier).call
end
end
+7 -38
View File
@@ -3,54 +3,23 @@ class Employer < ApplicationRecord
has_many :members, dependent: :destroy
accepts_nested_attributes_for :members, allow_destroy: true, reject_if: :all_blank
has_one :id_card_setup, class_name: 'IdCard::Setup', dependent: :destroy
has_many :plans, class_name: 'IdCard::Plan', through: :id_card_setup
scope :active, -> { where(active: true) }
scope :inactive, -> { where(active: false) }
# before_save :process_employer_logo
# before_save :process_employer_logo, if: :employer_logo_filename_changed?
# before_save :create_slug, if: :new_record?
before_save :create_slug, if: :will_save_change_to_name?
# before_save :set_active_status, unless: :will_save_change_to_active?
# after_save :process_employer_logo, if: :saved_change_to_employer_logo_filename?
before_save :deactivation_check, if: :will_save_change_to_active?
# def process_employer_logo
# # if self.employer_logo.present? && !self.employer_logo.is_a?(String)
# # self.card_logo_files.new(
# # filename: self.employer_logo.filename,
# # logo_type: 'employer',
# # image: self.employer_logo.data,
# # pl_plan_key: self.pl_plan_key || ""
# # )
# # end
# if self.employer_logo_filename.present? && self.employer_logo_filename.is_a?(String)
# image_file = CardLogoFile.find_by(filename: self.employer_logo_filename)
# if image_file.present?
# if self.employer_brand_logo.present?
# self.employer_brand_logo.update(card_logo_file: image_file)
# else
# self.create_employer_brand_logo(card_logo_file: image_file, logo_type: 'employer')
# end
# end
# end
# end
def create_slug
self.slug = Employer.employer_trim_name(self.name).parameterize
self.slug = Employer.employer_trim_name(name).parameterize
end
def set_active_status
self.active = (
self.pl_plan_key.present? &&
self.company_pb_entity_key.present? &&
self.plan_id.present? &&
self.group_number.present? &&
self.effective_date.present?
)
def deactivation_check
if active == false
id_card_setup&.update(active: false)
end
end
def id_card_enabled?
+15 -16
View File
@@ -6,26 +6,25 @@ module IdCard
scope :templates, -> { where(template: true) }
BENEFIT_FIELDS = ["Primary Visit",
"Specialist Visit",
"Urgent Care",
"INN-Ind Ded",
"INN-Family Ded",
"OON-Ind Ded",
"OON-Family Ded",
"Co-Insurance",
"INN-Ind OOP",
"INN-Family OOP",
"OON-Ind OOP",
"OON-Family OOP",
"Emergency Room",
"Preventive Care"].freeze
FARIOS_BENEFIT_FIELDS = ["Primary Visit", "Specialist Visit", "Urgent Care", "INN-Ind Ded", "INN-Family Ded", "OON-Ind Ded", "OON-Family Ded", "Co-Insurance", "INN-Ind OOP", "INN-Family OOP", "OON-Ind OOP", "OON-Family OOP", "Emergency Room", "Preventive Care"].freeze
TANDEMLOC_BENEFIT_FIELDS = ["Physician Visit", "Specialist Visit", "Urgent Care", "Deductible", "Co-Insurance", "Out-of-Pocket", "Emergency Room", "Preventive Care"].freeze
SMART_BENEFIT_FIELDS = [].freeze
after_initialize :build_plan_benefits, if: :new_record?
def build_plan_benefits
BENEFIT_FIELDS.each_with_index do |bene, i|
self.plan_benefits.build(benefit_desc: bene, sequence: (i + 1))
if plan_benefits.empty?
plan_benefit_fields = case setup&.card_template
when "TandemlocIDCard"
TANDEMLOC_BENEFIT_FIELDS
when "SmartIDCard"
SMART_BENEFIT_FIELDS
else
FARIOS_BENEFIT_FIELDS
end
plan_benefit_fields.each_with_index do |bene, i|
self.plan_benefits.build(benefit_desc: bene, sequence: (i + 1))
end
end
end
+43
View File
@@ -0,0 +1,43 @@
module Vhcs
class PbOrgUnit < VhcsRecord
self.table_name = 'PBOrgUnit'
alias_attribute :pb_entity_key, :PBEntityKey
alias_attribute :web_site, :WebSite
alias_attribute :federal_tax_id, :FederalTaxID
alias_attribute :duns_number, :DunsNumber
alias_attribute :company_number, :CompanyNumber
alias_attribute :company_location, :CompanyLocation
alias_attribute :division, :Division
alias_attribute :policy_number, :PolicyNumber
alias_attribute :when_last_changed, :WhenLastChanged
alias_attribute :who_last_changed, :WhoLastChanged
alias_attribute :mmsea_employer_size_g_1_1_5, :MMSEAEmployerSize_G115
alias_attribute :wait_period_delay_type_g_1_0_7, :WaitPeriodDelayType_G107
alias_attribute :wait_period, :WaitPeriod
alias_attribute :wait_period_unit_g_1_0_6, :WaitPeriodUnit_G106
def attributes
rails_like = {
pb_entity_key: self.pb_entity_key,
web_site: self.web_site,
federal_tax_id: self.federal_tax_id,
duns_number: self.duns_number,
company_number: self.company_number,
company_location: self.company_location,
division: self.division,
policy_number: self.policy_number,
when_last_changed: self.when_last_changed,
who_last_changed: self.who_last_changed,
mmsea_employer_size_g_1_1_5: self.mmsea_employer_size_g_1_1_5,
wait_period_delay_type_g_1_0_7: self.wait_period_delay_type_g_1_0_7,
wait_period: self.wait_period,
wait_period_unit_g_1_0_6: self.wait_period_unit_g_1_0_6,
}
super.merge(rails_like)
end
end
end
+23
View File
@@ -0,0 +1,23 @@
module Vhcs
class PlPlanGroupCode < VhcsRecord
self.table_name = 'PLPlanGroupCode'
alias_attribute :group_code, :GroupCode
alias_attribute :pl_plan_key, :PLPlanKey
alias_attribute :pl_cov_type_hdr_key, :PLCovTypeHdrKey
alias_attribute :group_code_desc, :GroupCodeDesc
def attributes
rails_like = {
group_code: self.group_code,
pl_plan_key: self.pl_plan_key,
pl_cov_type_hdr_key: self.pl_cov_type_hdr_key,
group_code_desc: self.group_code_desc,
}
super.merge(rails_like)
end
end
end
@@ -0,0 +1,27 @@
module AutomationService
class BatchEmployerUpdate
def initialize(pl_plan_keys)
@pl_plan_keys = pl_plan_keys
end
def call
sql_query = "SELECT PLPlanKey, PlanId, ShortDesc FROM PLPlanHeader
WHERE ActiveInactive = 'Active' AND PLPlanKey IN (#{@pl_plan_keys.join(',')})"
employer_plan_headers = VhcsRecord.connection.select_all(sql_query)
employer_update_futures = employer_plan_headers.map do |employer_plan_header|
Concurrent::Future.execute do
ActiveRecord::Base.connection_pool.with_connection do
UpdateEmployerJob.perform_later(employer_plan_header: employer_plan_header)
end
end
end
employer_update_futures.map(&:value)
end
end
end
# AutomationService::MemberUpdate('13', 337710)
@@ -21,13 +21,16 @@ module AutomationService
member_update_futures = vw_mb_members.map do |vw_mb_member|
Concurrent::Future.execute do
ActiveRecord::Base.connection_pool.with_connection do
UpdateMemberJob.perform_now(@pb_entity_key, employer.id, card_setup.has_divisions, card_setup.has_dental, vw_mb_member)
UpdateMemberJob.perform_now(vw_mb_member.pb_entity_key, employer.id, card_setup.has_divisions, card_setup.has_dental, vw_mb_member)
end
end
end
member_updates = member_update_futures.map(&:value).compact
employer.members = member_updates
if member_updates.empty? && employer.id_card_setup.active
employer.active = false
end
employer.save
end
@@ -0,0 +1,22 @@
module AutomationService
class EmployerPlansUpdate
def initialize(pl_plan_key)
@pl_plan_key = pl_plan_key
end
def call
# employer = Employer.includes(:id_card_setup).find_by(pl_plan_key: @pl_plan_key)
# card_setup = employer.id_card_setup
UpdateEmployerPlansJob.new.perform(@pl_plan_key)
# if employer.present?
# employer.save
# else
# Member.find_by(pb_entity_key: vw_mb_member[:pb_entity_key]).destroy
# end
end
end
end
# AutomationService::MemberUpdate('13', 337710)
@@ -1,15 +1,15 @@
module AutomationService
class EmployerUpdate
def initialize(pl_plan_key, full_sync = false)
@pl_plan_key = pl_plan_key
def initialize(employer_identifier, full_sync = false)
@employer_identifier = employer_identifier
@full_sync = full_sync
end
def call
# employer = Employer.includes(:id_card_setup).find_by(pl_plan_key: @pl_plan_key)
# employer = Employer.includes(:id_card_setup).find_by(employer_identifier: @employer_identifier)
# card_setup = employer.id_card_setup
UpdateEmployerJob.new.perform(@pl_plan_key, {}, @full_sync)
UpdateEmployerJob.new.perform(employer_identifier: @employer_identifier, full_sync: @full_sync)
# if employer.present?
# employer.save
# else
+109 -22
View File
@@ -1,33 +1,120 @@
<div class="bg-deepcove h-full w-full flex flex-col justify-start">
<div class="flex items-center">
<h1 class="font-bold text-4xl text-platinum my-5">Employers</h1>
<%= link_to new_employer_path, class: "flex justify-center items-center h-8 w-8 ml-2 mb-6 text-sm text-bronze bg-deepcove hover:bg-cobalt font-semibold p-1 rounded-lg border-2 border-cobalt" do %>
<%= link_to new_employer_path, class: "flex justify-center items-center h-8 w-8 ml-2 mb-6 text-sm text-bronze bg-deepcove hover:bg-cobalt font-semibold p-1 -l border-2 border-cobalt" do %>
<%= icon "clipboard-plus", library: "lucide" %>
<% end %>
</div>
<% plan_colors = IdCard::Setup::FORM_COLORS.push('copper', 'bronze').shuffle %>
<% @color_index = 0 %>
<h2 class="font-bold text-3xl text-brightlava my-5">In Process:</h2>
<% @employers.inactive.each_with_index do |emp, index| %>
<% item_color_index = @color_index == 0 ? 0 : @color_index % plan_colors.length %>
<div class="w-1/2 flex text-2xl text-platinum font-bold px-4 py-4 ml-10 space-x-4 rounded-lg border-l-5 border-b-2 <%= "border-#{plan_colors[item_color_index]}" %>">
<%= link_to emp.name, employer_path(emp.slug), class: "hover:text-#{plan_colors[item_color_index]}" %>
<div>
<%= "(Effective #{emp.effective_date})" %>
</div>
<% if @not_automation_ready.present? || @missing_keychain_initialization.present? || @missing_plans_initialization.present? || @missing_members_initialization.present? %>
<h2 class="font-bold text-3xl text-brightlava my-5">In Process:</h2>
<% no_employers_text = @not_automation_ready.present? ? "" : " NONE" %>
<h3 class="font-bold text-xl text-bronze my-5 ml-10">
<%= "Waiting for Groups Number/Pl Plan Key:#{no_employers_text}" %>
</h2>
<div class="flex flex-wrap w-full pl-20 pr-10 gap-x-4 gap-y-3">
<% @not_automation_ready.each_with_index do |emp, index| %>
<div class="w-[23%] inline-flex flex-col text-platinum font-bold px-4 rounded-l-lg border-l-5 border-b-2 border-bronze">
<div class="w-full flex text-xl">
<%= link_to emp.name, employer_path(emp.slug), class: "text-bronze hover:text-platinum" %>
</div>
<div class="w-full flex text-md font-medium">
<%= "(Effective #{emp.effective_date})" %>
</div>
</div>
<% end %>
</div>
<% no_employers_text = @missing_keychain_initialization.present? ? "" : " NONE" %>
<h3 class="font-bold text-xl text-verdigris-vivid my-5 ml-10">
<%= "Waiting for Employer to be created in VHCS:#{no_employers_text}" %>
</h2>
<div class="flex flex-wrap w-full pl-20 pr-10 gap-x-4 gap-y-3">
<% @missing_keychain_initialization.each_with_index do |emp, index| %>
<div class="w-[23%] inline-flex flex-col text-platinum font-bold px-4 rounded-l-lg border-l-5 border-b-2 border-verdigris-vivid">
<div class="w-full flex text-xl">
<%= link_to emp.name, employer_path(emp.slug), class: "text-verdigris-vivid hover:text-platinum" %>
</div>
<div class="w-full flex text-md font-medium">
<%= "(Effective #{emp.effective_date})" %>
</div>
</div>
<% end %>
</div>
<% no_employers_text = @missing_plans_initialization.present? ? "" : " NONE" %>
<h3 class="font-bold text-xl text-copper my-5 ml-10">
<%= "Waiting for Plans to be created in VHCS:#{no_employers_text}" %>
</h2>
<div class="flex flex-wrap w-full pl-20 pr-10 gap-x-4 gap-y-3">
<% @missing_plans_initialization.each_with_index do |emp, index| %>
<div class="w-[23%] inline-flex flex-col text-platinum font-bold px-4 rounded-l-lg border-l-5 border-b-2 border-copper">
<div class="w-full flex text-xl">
<%= link_to emp.name, employer_path(emp.slug), class: "text-copper hover:text-platinum" %>
</div>
<div class="w-full flex text-md font-medium">
<%= "(Effective #{emp.effective_date})" %>
</div>
</div>
<% end %>
</div>
<% no_employers_text = @missing_members_initialization.present? ? "" : " NONE" %>
<h3 class="font-bold text-xl text-bluemana my-5 ml-10">
<%= "Waiting for Inital Members to be created in VHCS:#{no_employers_text}" %>
</h2>
<div class="flex flex-wrap w-full pl-20 pr-10 gap-x-4 gap-y-3">
<% @missing_members_initialization.each_with_index do |emp, index| %>
<div class="w-[32%] inline-flex flex-col text-platinum font-bold px-4 rounded-l-lg border-l-5 border-b-2 border-bluemana">
<div class="w-full flex">
<%= link_to emp.name, employer_path(emp.slug), class: "text-bluemana hover:text-platinum" %>
</div>
<div class="w-full flex justify-between text-md font-medium">
<% member_counter_color = "text-".concat(emp.members.present? ? "limegreen" : "brightlava") %>
<div>
Members:
<span class="ml-2 <%= member_counter_color %>">
<%= emp.members.count %>
</span>
</div>
<div class="ml-2">
<%= "(Effective #{emp.effective_date})" %>
</div>
</div>
</div>
<% end %>
</div>
<% @color_index += 1 %>
<% end %>
<h2 class="font-bold text-3xl text-limegreen my-5">Live:</h2>
<% @employers.active.each_with_index do |emp, index| %>
<% item_color_index = @color_index == 0 ? 0 : @color_index % plan_colors.length %>
<div class="w-1/2 flex text-2xl text-platinum font-bold px-4 py-4 ml-10 space-x-4 rounded-lg border-l-5 border-b-2 <%= "border-#{plan_colors[item_color_index]}" %>">
<%= link_to "(#{emp.pl_plan_key}) - #{emp.name}", employer_path(emp.slug), class: "hover:text-#{plan_colors[item_color_index]}" %>
<div>
<%= "(#{emp.members.count} Members)" %>
<div class="flex flex-wrap w-full px-10 gap-x-4 gap-y-3">
<% @active_with_active_id_card_setup.order(:name).each_with_index do |emp, index| %>
<div class="w-[23%] inline-flex flex-col text-platinum font-bold px-4 rounded-l-lg border-l-5 border-b-2 border-atmosphere">
<div class="w-full flex text-xl space-x-4">
<%= link_to emp.name, employer_path(emp.slug), class: "text-atmosphere hover:text-platinum" %>
</div>
<div class="w-full flex text-md font-medium space-x-2">
<div>
Members:
<span class="ml-2">
<%= emp.members.count %>
</span>
</div>
</div>
</div>
</div>
<% @color_index += 1 %>
<% end %>
<% end %>
</div>
<h2 class="font-bold text-3xl text-[#ADADAD] my-5">Deactivated:</h2>
<div class="flex flex-wrap w-full px-10 gap-x-4 gap-y-3">
<% @deactivated.each_with_index do |emp, index| %>
<div class="w-[23%] inline-flex flex-col text-[#ADADAD] font-bold px-4 rounded-l-lg border-l-5 border-b-2 border-[#ADADAD]">
<div class="w-full flex text-xl space-x-4">
<%= link_to emp.name, employer_path(emp.slug), class: "text-platinum hover:text-bluemana" %>
</div>
<div class="w-full flex text-md font-medium space-x-2">
<div>
Members:
<span class="ml-2">
<%= emp.members.count %>
</span>
</div>
</div>
</div>
<% end %>
</div>
</div>
+3
View File
@@ -84,6 +84,9 @@
<%= link_to "General", employer_id_card_setup_index_path(employer_id: @employer.slug), data: { turbo: false }, class: "flex justify-center items-center w-full cursor-pointer bg-#{module_color} hover:bg-deepcove border-2 border-#{module_color} text-platinum font-bold px-3 rounded-lg h-10 transition duration-100" %>
<%= link_to "Plans", plans_employer_id_card_setup_index_path(employer_id: @employer.slug), data: { turbo: false }, class: "flex justify-center items-center w-full cursor-pointer bg-#{module_color} hover:bg-deepcove border-2 border-#{module_color} text-platinum font-bold px-3 rounded-lg h-10 transition duration-100" %>
<%= link_to 'Exceptions (Optional)', field_exceptions_employer_id_card_setup_index_path(employer_id: @employer.slug ), data: { turbo: false }, class: "flex justify-center items-center w-full cursor-pointer bg-#{module_color} hover:bg-deepcove border-2 border-#{module_color} text-platinum font-bold px-3 rounded-lg h-10 transition duration-100" %>
<% unless @employer.id_card_setup.active %>
<%= link_to 'Activate ID Cards', update_active_status_employer_id_card_setup_index_path(employer_id: @employer.slug ), data: { turbo: false }, class: "flex justify-center items-center w-full cursor-pointer bg-brightlava hover:bg-deepcove border-2 border-brightlava text-platinum font-bold px-3 rounded-lg h-10 transition duration-100" %>
<% end %>
</div>
</div>
<div class="grow-1 flex flex-col items-center w-full">
@@ -1,12 +1,13 @@
<div class="pl-1 w-full">
<%= plan_fields.text_field :title, label: { text: "Plan Title" }, class: "w-full", data: { add_plan_target: "plan" } %>
<%= plan_fields.text_field :title, label: { text: "Plan Title" }, class: "w-full", data: { add_plan_target: "plan", benefits_template_picker_target: "title" } %>
</div>
<% if plan_fields.object.persisted? %>
<div class="pl-1 w-full">
<%= plan_fields.text_field :pb_product_key, label: { text: "Plan Product Key" }, class: "w-full" %>
</div>
<%= plan_fields.hidden_field :id %>
<% else %>
<% end %>
<% unless plan_fields.object.setup.active %>
<div class="pl-1 pb-2 w-full">
<%= f.select :template_id, options_from_collection_for_select(@plan_templates, :id, :title), { prompt: "Select Plan Template", class: "w-full" }, { data: { action: "benefits-template-picker#fetchData" }} %>
</div>
+17 -17
View File
@@ -19,25 +19,25 @@ services:
- PGID=100
tty: true
stdin_open: true
depends_on:
db:
condition: service_healthy
# depends_on:
# db:
# condition: service_healthy
# redis:
# condition: service_started
db:
build:
context: .
dockerfile: Dockerfile.db
volumes:
- ./mssql-data:/var/opt/mssql
ports:
- "1434:1434"
healthcheck:
test: ["CMD", "/opt/mssql-tools/bin/sqlcmd", "-Usa", "-PBr1tt0nPassw0rd", "-Q", "select 1"]
interval: 10s
timeout: 3s
retries: 10
start_period: 10s
# db:
# build:
# context: .
# dockerfile: Dockerfile.db
# volumes:
# - ./mssql-data:/var/opt/mssql
# ports:
# - "1434:1434"
# healthcheck:
# test: ["CMD", "/opt/mssql-tools/bin/sqlcmd", "-Usa", "-PBr1tt0nPassw0rd", "-Q", "select 1"]
# interval: 10s
# timeout: 3s
# retries: 10
# start_period: 10s
# redis:
# image: redis
# volumes:
+2 -1
View File
@@ -32,7 +32,7 @@ Rails.application.routes.draw do
# get 'generate_full_page'
# end
# end
get 'plans/:id/get_plan_benefits', to: 'plans#get_plan_benefits'
get 'plans/:id/get_plan_template', to: 'plans#get_plan_template'
end
# resources :employer_setup
resources :employers do
@@ -48,6 +48,7 @@ Rails.application.routes.draw do
patch 'update_plans'
get 'field_exceptions'
patch 'update_field_exceptions'
get 'update_active_status'
end
end
end
+9 -3
View File
@@ -1,9 +1,15 @@
set :output, "./log/cron_log.log"
set :output, "log/cron_log.log"
set :environment, ENV['RAILS_ENV'] || 'development'
every 1.minute do
runner "Rails.logger.info 'Cron test ran at: ' + Time.now.to_s"
command "echo 'Cron test ran at: ' $(date) >> log/cron_log.log"
end
every 1.day, at: ['6:00 am', '6:00 pm'] do
rake "employer_automation:employer_members_update"
rake "employer_automation:employer_maintenance"
end
every '0,15,30,45 7-18 * * 1-5' do
rake "employer_automation:employer_update"
rake "employer_automation:employer_initialize"
end
@@ -10,6 +10,7 @@ class CreateMembers < ActiveRecord::Migration[7.2]
t.string :coverage_class
t.string :division
t.string :dental_plan_key
t.text :dependents
t.belongs_to :employer, foreign_key: true
t.belongs_to :id_card_plan, null: true, foreign_key: true
+2 -2
View File
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.2].define(version: 2026_04_09_175359) do
ActiveRecord::Schema[7.2].define(version: 2026_04_08_210447) do
create_table "employers", force: :cascade do |t|
t.string "name"
t.string "slug"
@@ -266,11 +266,11 @@ ActiveRecord::Schema[7.2].define(version: 2026_04_09_175359) do
t.string "coverage_class"
t.string "division"
t.string "dental_plan_key"
t.text "dependents"
t.bigint "employer_id"
t.bigint "id_card_plan_id"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.text "dependents"
t.index ["employer_id"], name: "index_members_on_employer_id"
t.index ["id_card_plan_id"], name: "index_members_on_id_card_plan_id"
end
+22 -345
View File
@@ -1,347 +1,24 @@
require "vips"
require "image_processing/vips"
def determine_id_card_templates(pl_plan_key)
case pl_plan_key
when "2"
"SmartIDCard"
when "3"
"TandemlocIDCard"
when "56"
"QRCodeIDCard"
else
"FairosRxIDCard"
seed_tasks = [
"seed_tasks:build_plan_templates",
"seed_tasks:build_provider_sections",
"seed_tasks:build_rx_sections",
"seed_tasks:build_network_logos",
"seed_tasks:build_employer_logos",
"seed_tasks:build_vendors",
"seed_tasks:build_carriers",
"seed_tasks:build_brokers",
"seed_tasks:build_employers",
"seed_tasks:determine_card_templates",
"seed_tasks:determine_network_fields",
"seed_tasks:determine_employer_fields",
"seed_tasks:build_members"
]
seed_tasks.each do |task_name|
Rake::Task[task_name].invoke
Rake::Task[task_name].reenable
end
end
def determine_id_card_rx(pl_plan_key)
if pl_plan_key == "56"
"TheHealthBus"
else
"FairosRx"
end
end
def determine_id_card_network(pl_plan_key)
cigna_groups = ["13","20","39","48","49","51","53","54","56","58","60","61","62","65","67","68","69"]
medcost_groups = ["4","5","16","23","33","55","57","59","63","66"]
old_cigna_groups = ["19","21"]
smart_medcost = ["2"]
tan_medcost = ["3"]
case
when cigna_groups.include?(pl_plan_key) || pl_plan_key.blank?
{ provider: "Cigna", network_logo: "CignaLogo.png", provider_section: "Cigna" }
when medcost_groups.include?(pl_plan_key)
{ provider: "MedCost", network_logo: "MedcostLogo.png", provider_section: "MedCost" }
when old_cigna_groups.include?(pl_plan_key)
{ provider: "Cigna", network_logo: "CignaLogo.png", provider_section: "Cigna (Beam/Stevens)" }
when smart_medcost.include?(pl_plan_key)
{ provider: "MedCost", network_logo: "MedcostLogo.png", provider_section: "MedCost (smART)" }
when tan_medcost.include?(pl_plan_key)
{ provider: "MedCost", network_logo: "MedcostLogo.png", provider_section: "MedCost (Tandemloc)" }
end
end
def determine_divisions(pl_plan_key)
division_employers = ["2", "16"]
if division_employers.include?(pl_plan_key)
true
else
false
end
end
def determine_dental(pl_plan_key)
dental_employers = ["2", "3"]
if dental_employers.include?(pl_plan_key)
true
else
false
end
end
def determine_card_color(pl_plan_key)
if pl_plan_key == "3"
"blue"
else
"white"
end
end
def determine_field_exceptions(pl_plan_key)
exceptions_map = {
"3" => [{
exception_type: "state",
exception_values: ["AZ", "MO", "IL"],
field_exception_items_attributes: [
{field_name: "provider_section", provider_section_id: 3},
{field_name: "network_logo", network_logo_id: 8}
]
}],
"13" => [{
exception_type: "zipcode",
exception_values: ["14422", "14623", "14624"],
field_exception_items_attributes: [
{field_name: "network_logo", network_logo_id: 3}
]
}],
"16" => [{
exception_type: "state",
exception_values: ["VA"],
field_exception_items_attributes: [
{field_name: "medical_eff_date", field_value: "12/01/2025"},
{field_name: "provider_section", provider_section_id: 7},
{field_name: "network_logo", network_logo_id: 6}
]
}],
"21" => [{
exception_type: "state",
exception_values: ["VA"],
field_exception_items_attributes: [
{field_name: "network_logo", network_logo_id: 3}
]
}],
"51" => [{
exception_type: "zipcode",
exception_values: ["41456", "41149", "41124"],
field_exception_items_attributes: [
{field_name: "network_logo", network_logo_id: 4}
]
}],
"55" => [{
exception_type: "state",
exception_values: ["CA", "GA"],
field_exception_items_attributes: [
{field_name: "provider_section", provider_section_id: 8},
{field_name: "network_logo", network_logo_id: 5}
]
}],
"62" => [
{
exception_type: "zipcode",
exception_values: ["49420", "48167"],
field_exception_items_attributes: [
{field_name: "network_logo", network_logo_id: 2}
]
},
{
exception_type: "zipcode",
exception_values: ["55419", "55379"],
field_exception_items_attributes: [
{field_name: "network_logo", network_logo_id: 1}
]
}
],
"65" => [
{
exception_type: "zipcode",
exception_values: ["48430", "44842", "48649"],
field_exception_items_attributes: [
{field_name: "network_logo", network_logo_id: 2}
]
},
{
exception_type: "zipcode",
exception_values: ["55372", "55021"],
field_exception_items_attributes: [
{field_name: "network_logo", network_logo_id: 1}
]
},
{
exception_type: "zipcode",
exception_values: ["18042", "18080"],
field_exception_items_attributes: [
{field_name: "network_logo", network_logo_id: 10}
]
}
],
"66" => [{
exception_type: "state",
exception_values: ["GA"],
field_exception_items_attributes: [
{field_name: "provider_section", provider_section_id: 8},
{field_name: "network_logo", network_logo_id: 5}
]
}]
}
if exceptions_map[pl_plan_key].present?
exceptions_map[pl_plan_key]
else
nil
end
end
puts "[**** IMPORT ID CARD TABLES ****]"
## SET UP DEFAULT LEVEL360 PLANS FOR PLAN PICKER
# temp_1 = IdCardBenefitsTemplate.create(title: "Rebekah's Template")
# (1..14).each do |seq|
# IdCardBenefit.create(sequence: seq, benefit: "greatest hits vol #{seq}", id_card_benefits_template: temp_1)
# end
##---------------- Provider/Claims Setup------------------------------------
puts "Importing Card Provider/Claims Information"
default_provider_codes = ["5", "2"]
needed_codes_mapping = {
"0": "MedCost VA Plus Network",
"2": "MedCost",
"3": "AHA Preferred",
"5": "Cigna",
"6": "Cigna (Beam/Stevens)",
A: "AHA",
M: "MedCost (smART)",
T: "MedCost (Tandemloc)"
}.stringify_keys
needed_codes = needed_codes_mapping.keys
vhcs_cp = Vhcs::HlidCardProvider.where(provider_code: needed_codes)
vhcs_cp.each do |vhcs|
attributes_hash = vhcs.attributes.except(:provider_code, :group_number)
attributes_hash.delete_if { |key, value| !key.to_s.include?("_") }
if default_provider_codes.include?(vhcs.provider_code)
attributes_hash[:default] = true
end
attributes_hash[:title] = needed_codes_mapping[vhcs.provider_code]
puts "-- #{attributes_hash[:title]}"
IdCard::ProviderSection.find_or_create_by(attributes_hash)
end
##---------------- Rx info Setup------------------------------------
puts "Importing Card Rx Information"
Vhcs::HlrxCrosRef.all.each do |vhcs|
rx = IdCard::RxSection.find_or_create_by(help_desk: vhcs.help_desk, customer_service: vhcs.customer_service, web_url: vhcs.web_url)
title = rx.web_url.gsub(/^www\./, '').gsub(/\.com\Z/, '')
unless title.match?(/\A[A-Z]/)
title = title.capitalize
end
puts "-- #{title}"
rx.title = title
rx.save
end
##---------------- Network Logos Setup------------------------------------
puts "Importing Network Logos"
folder_path = Rails.root.join('logo_files', 'network')
file_names = Dir.children(folder_path)
default_network_logos = ["CignaLogo.png", "MedCostLogo.png"]
file_names.each do |logo_upload|
puts "-- #{logo_upload}"
new_logo = ImageProcessorService.new("logo_files/network/#{logo_upload}", "Network").call
if default_network_logos.include?(logo_upload)
new_logo.default = true
end
new_logo.active = true
new_logo.save
end
##---------------- Active Employer Logo Setup------------------------------------
puts "Importing Employer Logos"
folder_path = Rails.root.join('logo_files', 'employer')
file_names = Dir.children(folder_path)
file_names.each do |logo_upload|
puts "-- #{logo_upload}"
new_logo = ImageProcessorService.new("logo_files/employer/#{logo_upload}", "Employer").call
new_logo.active = true
new_logo.save
end
puts "[**** IMPORT EMPLOYERS ****]"
##---------------- Import Employer/Member (VHCS) ------------------------------------
puts "Importing Employers From VHCS"
Rake::Task["employer:vhcs_sync_all"].invoke
# acentria = Carrier.find_or_create_by!(name: 'Acentria')
# mcswain_broker = Broker.find_or_create_by!(name: 'Tom McSwain') do |mc|
# mc.carrier = acentria
# end
# mcswain_employers = HebWeb::BrokerXRef.where(pl_plan_key: 99).pluck(:employer_pl_plan_key)
# Imports employers and members from VHCS
# use rake tasks
##---------------- Import Employers (Word Docs) ------------------------------------
# puts "Importing Employers From Word Docs"
# folder_path = Rails.root.join('employer_word_docs')
# file_names = Dir.children(folder_path)
# file_names.each do |word_doc|
# puts "-- Processing #{word_doc}"
# new_employer = BenefitsWordDocService::WordDocProcessor.new("employer_word_docs/#{word_doc}").call
# if new_employer.save
# puts "Imported #{new_employer.name}"
# end
# end
##---------------- Update ID Card Setups------------------------------------
puts "[**** UPDATE EMPLOYER ID CARD SETUPS ****]"
IdCard::Setup.all.each do |setup|
setup.card_template = determine_id_card_templates(setup.pl_plan_key)
setup.card_color = determine_card_color(setup.pl_plan_key)
setup.has_divisions = determine_divisions(setup.pl_plan_key)
setup.has_dental = determine_dental(setup.pl_plan_key)
network_information = determine_id_card_network(setup.pl_plan_key)
setup.network_provider = network_information[:provider]
ps = IdCard::ProviderSection.find_by(title: network_information[:provider_section])
setup.provider_section_id = ps.id
nl = IdCard::NetworkLogo.find_by(filename: network_information[:network_logo])
setup.network_logo_id = nl.id
rx_title = determine_id_card_rx(setup.pl_plan_key)
rs = IdCard::RxSection.find_by(title: rx_title)
setup.rx_section_id = rs.id
employer_name = Employer.employer_trim_name(setup.employer.name)
name_segments = employer_name.titleize.split
name_segments.each do |segment|
logo = IdCard::EmployerLogo.where("filename LIKE ?", "%#{segment}%")
if logo&.first
setup.employer_logo = logo.first
break
end
end
card_exceptions = determine_field_exceptions(setup.pl_plan_key)
if card_exceptions.present?
setup.field_exceptions.create(card_exceptions)
# card_exceptions.each do |exc|
# setup.field_exceptions.create(exc)
# end
end
if setup.pl_plan_key.present?
setup.active = true
end
setup.save
end
# 15, 18, 19, 20, 13, 21
+22 -7
View File
@@ -1,17 +1,32 @@
namespace :employer_automation do
desc "Update Necessary Employer Values"
# rake employer:vhcs_sync_all
task employer_update: :environment do
Employer.missing_keychain_values.map(&:sync_with_vhcs)
desc "Employer Initialization Automation"
# rake employer_automation:employer_initialize
task employer_initialize: :environment do
Employer.missing_keychain_initialization.map(&:sync_with_vhcs)
Employer.missing_plans_initialization.map(&:sync_plans_with_vhcs)
Employer.missing_initial_members.map(&:sync_members_with_vhcs)
end
desc "Employer Initialization Automation Test"
# rake employer_automation:employer_initialize_test
task employer_initialize_test: :environment do
if (missing_keychain = Employer.missing_keychain_initialization).exists?
missing_keychain.map(&:sync_with_vhcs)
elsif (missing_plans = Employer.missing_plans_initialization).exists?
missing_plans.map(&:sync_plans_with_vhcs)
elsif (missing_members = Employer.missing_members_initialization).exists?
missing_members.map(&:sync_members_with_vhcs)
end
end
desc "Update Employer Members"
# rake employer:import_members_from_vhcs[67]
task employer_members_update: :environment do
desc "Employer Maintenance Automation"
# rake employer_automation:employer_maintenance
task employer_maintenance: :environment do
Employer.automation_ready.map(&:sync_with_vhcs)
Employer.active.map(&:sync_plans_with_vhcs)
Employer.active.map(&:sync_members_with_vhcs)
end
+26 -8
View File
@@ -1,4 +1,6 @@
require 'json'
require "vips"
require "image_processing/vips"
namespace :seed_tasks do
@@ -30,6 +32,7 @@ namespace :seed_tasks do
plan_items = page_rows.map { |row| row[index] }
plan_items.shift
puts "-- #{plan}"
plan = IdCard::Plan.create!(title: plan, template: true)
doc_to_sequence_map = {
0 => 4,
@@ -48,7 +51,6 @@ namespace :seed_tasks do
# 9 => 8,
# 10 => 8,
plan_items.each_with_index do |item, i|
puts "-- #{item}"
sequence = doc_to_sequence_map[i]
if sequence.present?
benefit = plan.plan_benefits.find_by(sequence: sequence)
@@ -64,6 +66,9 @@ namespace :seed_tasks do
benefit.update(benefit: coins)
end
end
preventive_care = "100%"
benefit = plan.plan_benefits.last
benefit.update(benefit: preventive_care)
end
end
end
@@ -94,7 +99,6 @@ namespace :seed_tasks do
end
attributes_hash[:title] = needed_codes_mapping[vhcs.provider_code]
puts "-- #{attributes_hash[:title]}"
IdCard::ProviderSection.find_or_create_by(attributes_hash)
end
@@ -111,7 +115,6 @@ namespace :seed_tasks do
title = title.capitalize
end
puts "-- #{title}"
rx.title = title
rx.save
end
@@ -155,6 +158,12 @@ namespace :seed_tasks do
## Build Entities Tables
desc "Build Initial Vendors"
# rake seed_tasks:build_vendors
task build_vendors: :environment do
puts "Importing Vendors"
end
desc "Build Initial Carriers"
# rake seed_tasks:build_carriers
task build_carriers: :environment do
@@ -175,8 +184,9 @@ namespace :seed_tasks do
plan_headers = VhcsRecord.connection.select_all(sql_query)
plan_headers.each do |plan_header|
employer = UpdateEmployerJob.perform_now(plan_header['PLPlanKey'], plan_header, true)
employer = UpdateEmployerJob.perform_now(employer_plan_header: plan_header, full_sync: true)
puts "-- #{employer.name}"
UpdateEmployerPlansJob.new.perform(employer.pl_plan_key)
# employer_plans = employer.id_card_setup.plans
vhcs_plans = Vhcs::PbProduct.where(company_pb_entity_key: employer.company_pb_entity_key, is_active: 255)
vhcs_plans.each do |vp|
@@ -200,6 +210,10 @@ namespace :seed_tasks do
benefit.update(benefit: vb.benefit)
end
end
if vhcs_plans.empty?
employer.active = false
end
employer.save
end
end
@@ -209,6 +223,9 @@ namespace :seed_tasks do
task build_members: :environment do
puts "Importing Members"
Employer.all.map(&:sync_members_with_vhcs)
Employer.left_outer_joins(:members)
.where(members: { id: nil })
.update_all(active: false)
end
## Build Employer ID Card Setups
@@ -260,7 +277,7 @@ namespace :seed_tasks do
# rake seed_tasks:determine_network_fields
task determine_network_fields: :environment do
puts "Updating Network Fields"
cigna_groups = ["13","20","39","48","49","51","53","54","56","58","60","61","62","65","67","68","69"]
cigna_groups = ["13","20","39","48","49","50","51","53","54","56","58","60","61","62","65","67","68","69"]
medcost_groups = ["4","5","16","23","33","55","57","59","63","66"]
old_cigna_groups = ["19","21"]
smart_medcost = ["2"]
@@ -268,6 +285,7 @@ namespace :seed_tasks do
IdCard::Setup.all.each do |setup|
pl_plan_key = setup.pl_plan_key
puts pl_plan_key
setup_update_attrs = case
when cigna_groups.include?(pl_plan_key) || pl_plan_key.blank?
{ network_provider: "Cigna", network_logo: "CignaLogo.png", provider_section: "Cigna" }
@@ -312,10 +330,10 @@ namespace :seed_tasks do
json_file_path = Rails.root.join('seed_docs', 'json_files', 'card_exceptions.json')
file_content = File.read(json_file_path)
card_exceptions_map = JSON.parse(file_content)
if card_exceptions_map[pl_plan_key].present?
setup.field_exceptions.create(card_exceptions_map[pl_plan_key])
if card_exceptions_map[setup.pl_plan_key].present?
setup.field_exceptions.create(card_exceptions_map[setup.pl_plan_key])
end
setup.active = setup.employer.active
setup.save
end
File diff suppressed because it is too large Load Diff
Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB