automate employer setup import from word and manual entry working

This commit is contained in:
Jason Jordan
2025-12-03 11:42:15 -05:00
parent 3fbece7da6
commit 78ce415b94
44 changed files with 1012 additions and 339 deletions
+2
View File
@@ -75,3 +75,5 @@ yarn-debug.log*
/app/assets/builds/*
!/app/assets/builds/.keep
/mssql-data
+2
View File
@@ -82,3 +82,5 @@ gem 'tiny_tds'
gem 'devise'
gem 'pundit'
gem "tailwindcss-rails"
gem 'docx'
gem 'rubyzip'
+5
View File
@@ -115,6 +115,9 @@ GEM
responders
warden (~> 1.2.3)
diff-lcs (1.6.2)
docx (0.10.0)
nokogiri (~> 1.13, >= 1.13.0)
rubyzip (>= 2.0, < 4)
drb (2.2.3)
erb (5.1.3)
erubi (1.13.1)
@@ -389,6 +392,7 @@ DEPENDENCIES
bundler-audit
capybara
devise
docx
importmap-rails
jbuilder
pry-rails
@@ -400,6 +404,7 @@ DEPENDENCIES
rubocop-rails
rubocop-rails-omakase
rubocop-rspec
rubyzip
selenium-webdriver
sprockets-rails
stimulus-rails
+18
View File
@@ -5,14 +5,32 @@
--color-deepcove: #04153E;
/* medium dark blue */
--color-bluetang: #2A4B6F;
/* medium dark blue */
--color-bluetang-tinted: #223C59;
/* bright blue */
--color-atmosphere: #0096E0;
/* bright blue */
--color-atmosphere-tinted: #007AB8;
/* light blue */
--color-bluemana: #6AC8F1;
/* light blue */
--color-bluemana-tinted: #44BBEE;
/* cobalt blue */
--color-cobalt: #0047AB;
/* cobalt blue */
--color-cobalt-tinted: #003B8F;
/* platinum */
--color-platinum: #E0E0E0;
/* copper */
--color-copper: #B06E30;
/* copper */
--color-copper-tinted: #905A27;
/* bronze */
--color-bronze: #D38F4A;
/* bronze */
--color-bronze-tinted: #C57A30;
/* oxidized copper/bronze green-blue */
--color-verdigris: #588288;
/* oxidized copper/bronze green-blue */
--color-verdigris-tinted: #496A6F;
}
+136 -101
View File
@@ -1,20 +1,36 @@
class EmployerSetupController < ApplicationController
def new
# session.delete(:employer_setup_data)
session.clear()
# puts "Start"
# puts session[:employer_setup_data]
if session[:employer_setup_data].blank?
session[:employer_setup_data] = {}
end
session[:employer_setup_data]['current_step'] = 'network_exceptions'
session[:employer_setup_data]['pl_plan_key'] = 82
@top_form = EmployerSetupForm.new(session[:employer_setup_data])
case @top_form.current_step
when 'general_information'
@form = EmployerSetupGeneralInformationForm.new(session[:employer_setup_data]&.dig('general_information_data'))
when 'plans'
@form = EmployerSetupPlansForm.new(session[:employer_setup_data]&.dig('plans_data'))
when 'network_exceptions'
@form = EmployerSetupNetworkExceptionsForm.new(session[:employer_setup_data]&.dig('network_exceptions_data'))
when 'summary'
if @top_form.current_step != 'summary'
@form = form_for_step
else
@form = @top_form
end
# case @top_form.current_step
# when 'general_information'
# @form = EmployerSetupGeneralInformationForm.new(session[:employer_setup_data]&.dig('general_information_data'))
# when 'plans'
# @form = EmployerSetupPlansForm.new(session[:employer_setup_data]&.dig('plans_data'))
# when 'network_exceptions'
# @form = EmployerSetupNetworkExceptionsForm.new(session[:employer_setup_data]&.dig('network_exceptions_data'))
# when 'summary'
# @form = @top_form
# end
render @top_form.current_step_view
end
def create
# puts session[:employer_setup_data]
@top_form = EmployerSetupForm.new(session[:employer_setup_data])
if @top_form.current_step != 'summary'
if process_step(@top_form.current_step)
@@ -32,43 +48,43 @@ class EmployerSetupController < ApplicationController
end
end
case @top_form.current_step
when 'general_information'
@form = EmployerSetupGeneralInformationForm.new(general_information_params)
if @form.valid?
session[:employer_setup_data]['general_information_data'] = general_information_params
session[:employer_setup_data]['current_step'] = @top_form.next_step
redirect_to new_employer_setup_path
else
render @top_form.current_step_view
end
when 'plans'
@form = EmployerSetupPlansForm.new(plans_params)
if @form.valid?
session[:employer_setup_data]['plans_data'] = plans_params
session[:employer_setup_data]['current_step'] = @top_form.next_step
redirect_to new_employer_setup_path
else
render @top_form.current_step_view
end
when 'network_exceptions'
@form = EmployerSetupNetworkExceptionsForm.new(network_exceptions_params)
if @form.valid?
session[:employer_setup_data]['network_exceptions_data'] = network_exceptions_params
session[:employer_setup_data]['current_step'] = @top_form.next_step
redirect_to new_employer_setup_path
else
render @top_form.current_step_view
end
when 'summary'
@form = EmployerSetupForm.new(session[:employer_setup_data])
if @form.save
session.delete(:employer_setup_data)
redirect_to root_path, notice: "Employer setup successfully!"
else
render @top_form.current_step_view
end
end
# case @top_form.current_step
# when 'general_information'
# @form = EmployerSetupGeneralInformationForm.new(general_information_params)
# if @form.valid?
# session[:employer_setup_data]['general_information_data'] = general_information_params
# session[:employer_setup_data]['current_step'] = @top_form.next_step
# redirect_to new_employer_setup_path
# else
# render @top_form.current_step_view
# end
# when 'plans'
# @form = EmployerSetupPlansForm.new(plans_params)
# if @form.valid?
# session[:employer_setup_data]['plans_data'] = plans_params
# session[:employer_setup_data]['current_step'] = @top_form.next_step
# redirect_to new_employer_setup_path
# else
# render @top_form.current_step_view
# end
# when 'network_exceptions'
# @form = EmployerSetupNetworkExceptionsForm.new(network_exceptions_params)
# if @form.valid?
# session[:employer_setup_data]['network_exceptions_data'] = network_exceptions_params
# session[:employer_setup_data]['current_step'] = @top_form.next_step
# redirect_to new_employer_setup_path
# else
# render @top_form.current_step_view
# end
# when 'summary'
# @form = EmployerSetupForm.new(session[:employer_setup_data])
# if @form.save
# session.delete(:employer_setup_data)
# redirect_to root_path, notice: "Employer setup successfully!"
# else
# render @top_form.current_step_view
# end
# end
end
def update
@@ -85,70 +101,89 @@ class EmployerSetupController < ApplicationController
private
def general_information_params
params.require(:employer_setup_general_information_form).permit(
:name,
:employer_logo,
:group_number,
:dental,
:pl_plan_key,
:effect_date,
:number_of_plans,
:network,
:number_of_additional_network_logos
)
end
# def general_information_params
# params.require(:employer_setup_general_information_form).permit(
# :name,
# :employer_logo,
# :group_number,
# :dental,
# :pl_plan_key,
# :effect_date,
# :number_of_plans,
# :network,
# :number_of_additional_network_logos
# )
# end
def plans_params
params.require(:employer_setup_plans_form).permit(
plans: permited_plans_keys,
benefit_descs: benefit_sequence_keys
)
end
# def plans_params
# params.require(:employer_setup_plans_form).permit(
# plans: permited_plans_keys,
# benefit_descs: benefit_sequence_keys
# )
# end
def network_exceptions_params
params.require(:employer_setup_network_exceptions_form).permit(
network_exceptions: [:network_logo, exceptions: [:type, :value]],
)
# def network_exceptions_params
# params.require(:employer_setup_network_exceptions_form).permit(
# network_exceptions: [:network_logo, exceptions: [:type, :value]],
# )
# end
def form_for_step
step_name = @top_form.current_step
form_method = "EmployerSetup#{step_name.camelize}Form".constantize
form_method.new()
end
def process_step(step_name)
form_name = "employer_setup_#{step_name}_form".camelize.constantize
form_params_name = "#{step_name}_params".to_sym
allowed_params = [:general_information_params, :plans_params, :network_exceptions_params]
if allowed_params.include?(form_params_name)
form_params = send(form_params_name)
@form = form_name.new(form_params)
if @form.valid?
session[:employer_setup_data]["#{step_name}_data"] = form_params
@form_method = "EmployerSetup#{step_name.camelize}Form".constantize
session_data_name = "#{step_name}_data"
puts "1--------------params----"
puts params
puts "8--------------session----"
puts session[:employer_setup_data]
@form = @form_method.new(params)
if @form.pl_plan_key.blank?
@form.pl_plan_key = session[:employer_setup_data]['pl_plan_key']
end
if @form.valid? && @form.save
pl_plan_key = @top_form.pl_plan_key || @form.pl_plan_key
session[:employer_setup_data] = {current_step: step_name, pl_plan_key: pl_plan_key}
# form_fields = @form.attributes.merge!(global_params(step_name))
# session[:employer_setup_data][session_data_name] = form_fields
# session[:employer_setup_data].merge!(global_params(step_name))
# puts session[:employer_setup_data][session_data_name]
true
else
false
end
end
false
def step_params(step_name)
form_name_sym = "employer_setup_#{step_name}_form".to_sym
params.require(form_name_sym).permit(@form_method.permitted_params)
end
session[:employer_setup_data]['current_step'] = @top_form.next_step
redirect_to new_employer_setup_path
else
render @top_form.current_step_view
end
def global_params(step_name)
form_name_sym = "employer_setup_#{step_name}_form".to_sym
params.require(form_name_sym).permit(EmployerSetupForm.permitted_params)
end
when 'general_information'
@form = EmployerSetupGeneralInformationForm.new(general_information_params)
if @form.valid?
session[:employer_setup_data]['general_information_data'] = general_information_params
session[:employer_setup_data]['current_step'] = @top_form.next_step
redirect_to new_employer_setup_path
else
render @top_form.current_step_view
end
# def process_step(step_name)
# form_name = "employer_setup_#{step_name}_form".camelize.constantize
# form_params_name = "#{step_name}_params".to_sym
# allowed_params = [:general_information_params, :plans_params, :network_exceptions_params]
# if allowed_params.include?(form_params_name)
# form_params = send(form_params_name)
# @form = form_name.new(form_params)
# if @form.valid?
# session[:employer_setup_data]["#{step_name}_data"] = form_params
# true
# else
# false
# end
# end
# false
# end
# def employer_setup_params
# params.require(:employer_setup_form).permit(
@@ -167,13 +202,13 @@ class EmployerSetupController < ApplicationController
# )
# end
def benefit_sequence_keys
(1..14).map { |i| i.to_s.to_sym }
end
# def benefit_sequence_keys
# (1..14).map { |i| i.to_s.to_sym }
# end
def permited_plans_keys
benefit_sequence_keys.push(:plan_id)
end
# def permited_plans_keys
# benefit_sequence_keys.push(:plan_id)
# end
# def plans_params
# plans_keys = params[:plans]&.keys || []
@@ -35,7 +35,7 @@ class IdCardBenefitsTemplatesController < ApplicationController
@id_card_template_benefits = IdCardTemplate.find_by(title: "BLANK").id_card_template_benefits
end
def get_templates_benefits
def get_template_benefits
@id_card_benefits = IdCardBenefitsTemplate.find(params[:id]).id_card_benefits
render json: @id_card_benefits.as_json
end
+43 -20
View File
@@ -5,19 +5,33 @@ class EmployerSetupForm
FIRST_STEP = "general_information"
attribute :current_step, :string, default: FIRST_STEP
attribute :general_information_data
attribute :plans_data
attribute :network_exceptions_data
attribute :pl_plan_key, :string
def initialize(params = {})
# if params.present?
# params = permitted_params(params)
# end
super(params)
unless self.steps.first == FIRST_STEP
raise StepMisalignmentError, "FIRST_STEP does not match first entry in steps"
end
@general_information_data = EmployerSetupGeneralInformationForm.new(attributes[:general_information_data])
@plans_data = EmployerSetupPlansForm.new(attributes[:plans_data])
@network_exceptions_data = EmployerSetupNetworkExceptionsForm.new(attributes[:network_exceptions_data])
# @general_information_data = EmployerSetupGeneralInformationForm.new(attributes[:general_information_data])
# @plans_data = EmployerSetupPlansForm.new(attributes[:plans_data])
# @network_exceptions_data = EmployerSetupNetworkExceptionsForm.new(attributes[:network_exceptions_data])
end
# def self.form_session_init
# {
# general_information_data: {},
# plans_data: {},
# network_exceptions_data: {}
# }
# end
# def steps
# %w[general_information plans network_exceptions summary]
# end
def steps
%w[general_information plans network_exceptions summary]
end
@@ -29,29 +43,38 @@ class EmployerSetupForm
def next_step
index = steps.index(current_step)
if index && index < steps.length - 1
if steps[index + 1] == 'network_exceptions' && general_information_data.number_of_additional_network_logos == 0
steps[index + 2]
else
steps[index + 1]
end
end
end
def previous_step
index = steps.index(current_step)
steps[index - 1] if index && index > 0
end
def save
if valid?
pl_plan_key = attributes[:general_information_data][:pl_plan_key]
EmployerSetupGeneralInformationForm.new(attributes[:general_information_data]).save
EmployerSetupPlansForm.new(attributes[:plans_data]).save(pl_plan_key)
EmployerSetupNetworkExceptionsForm.new(attributes[:network_exceptions_data]).save(pl_plan_key)
true
else
false
end
def permitted_params(params)
params.require(:employer_setup_data).permit(
:pl_plan_key,
:current_step
)
end
def self.permitted_params
[
:pl_plan_key,
:current_step
]
end
# def save
# if valid?
# EmployerSetupGeneralInformationForm.new(attributes[:general_information_data]).save
# EmployerSetupPlansForm.new(attributes[:plans_data]).save
# EmployerSetupNetworkExceptionsForm.new(attributes[:network_exceptions_data]).save
# true
# else
# false
# end
# end
end
@@ -5,27 +5,48 @@ class EmployerSetupGeneralInformationForm
attribute :name, :string
attribute :employer_logo
attribute :group_number, :string
attribute :dental, :boolean
attribute :dental, :boolean, default: false
attribute :pl_plan_key, :string
attribute :effect_date, :string
attribute :number_of_plans, :integer
# attribute :number_of_plans, :integer
attribute :network, :string
attribute :number_of_additional_network_logos, :integer
# attribute :number_of_additional_network_logos, :integer
validates :name, presence: true
validates :employer_logo, presence: true
validates :group_number, presence: true
validates :pl_plan_key, presence: true
validates :effect_date, presence: true
validates :number_of_plans, presence: true
# validates :number_of_plans, presence: true
validates :network, presence: true
# validates :number_of_additional_network_logos, presence: true if network = "cigna+"
# def initialize(params = {})
# super(params)
# # Ensure the attribute is a hash after initialization
# @benefit_descs = params[:benefit_descs].to_h if params[:benefit_descs]
# end
# def initialize(attributes = {})
# if attributes
# permitted_attributes = form_strong_params(attributes)
# super(permitted_attributes)
# end
def initialize(params = {})
if params.present?
params = permitted_params(params)
end
super(params)
end
def permitted_params(params)
params.require(:employer_setup_general_information_form).permit(
:name,
:employer_logo,
:group_number,
:dental,
:pl_plan_key,
:effect_date,
:number_of_plans,
:network,
:number_of_additional_network_logos
)
end
def save
# Implement logic to save data to models after all steps are complete
@@ -40,8 +61,8 @@ class EmployerSetupGeneralInformationForm
)
# Replace fairos_info with template like for benefits
fairos_info = Vhcs::HLRXCrosRef.where(pl_plan_key: 52).first
hlrx_cros_ref = Vhcs::HLRXCrosRef.create!(
fairos_info = Vhcs::HlrxCrosRef.where(pl_plan_key: 52).first
hlrx_cros_ref = Vhcs::HlrxCrosRef.create!(
group_no: group_number,
rx_group_id: group_number,
help_desk: fairos_info.help_desk,
@@ -51,15 +72,26 @@ class EmployerSetupGeneralInformationForm
)
web_employer = BrittonWeb::Employers.create!(
name: name,
pl_plan_key: pl_plan_key,
dental_plan: dental,
single_card_template: 'FairosRxIDCard',
logo: employer_logo.filename
logo: employer_logo.original_filename
)
default_network_logo =
case
when network.include?("cig")
"CignaLogo.png"
when network.include?("med")
"Logo_MC_PMS.png"
else
"CignaLogo.png"
end
BrittonWeb::NetworkLogos.create!(
employer: web_employer,
net_logo: network,
employer_id: web_employer.id,
net_logo: default_network_logo,
default: true
)
@@ -4,30 +4,83 @@ class EmployerSetupNetworkExceptionsForm
Network_exception = Struct.new(:network_logo, :exceptions)
attribute :network_exceptions, :array_of_items, default: -> { [] }
attribute :pl_plan_key, :string
attribute :number_of_additional_network_logos, :integer
# validates :network_exceptions, presence: true if number_of_additional_network_logos > 0
# def initialize(params = {})
# super(params)
# # Ensure the attribute is a hash after initialization
# @benefit_descs = params[:benefit_descs].to_h if params[:benefit_descs]
# end
def initialize(params = {})
if params.present? && params[:employer_setup_network_exceptions_form].is_a?(ActionController::Parameters)
params = permitted_params(params)
end
super(params)
end
def save(pl_plan_key)
def permitted_params(params)
params.require(:employer_setup_network_exceptions_form).permit(
network_exceptions: [
:network_logo,
exceptions: [
:type,
:value
]
]
)
end
# def self.permitted_params
# [
# network_exceptions: [
# :network_logo,
# exceptions: [
# :type,
# :value
# ]
# ]
# ]
# end
def pull_from_employer_setup_form(attributes = {})
if attributes['pl_plan_key']
self.pl_plan_key = attributes['pl_plan_key']
end
if attributes['number_of_additional_network_logos']
self.number_of_additional_network_logos = attributes['number_of_additional_network_logos']
end
end
def process_for_save(network_exceptions)
ne_array = []
network_exceptions.first.each do |ne|
processed_ne = ne.last
exceptions_array = []
processed_ne['exceptions'].each do |e|
exceptions_array.push(e.last)
end
processed_ne['exceptions'] = exceptions_array
ne_array.push(processed_ne)
end
ne_array
end
def save
# Implement logic to save data to models after all steps are complete
# For example, create a User record with the collected data
if valid?
employer = BrittonWeb::Employers.find_by(pl_plan_key: pl_plan_key)
network_exceptions.each do |ne|
network_exceptions_data = process_for_save(network_exceptions)
network_exceptions_data.each do |ne|
ne['exceptions'].each do |ex|
BrittonWeb::NetworkLogos.create!(
employer: employer,
net_logo: ne.network_logo,
exception_type: ne.type,
exception_value: ne.value,
employer_id: employer.id,
net_logo: ne['network_logo'].original_filename,
exception_type: ex['type'].downcase,
exception_value: ex['value'],
default: false
)
end
end
true
else
false
+115 -16
View File
@@ -2,40 +2,111 @@ class EmployerSetupPlansForm
include ActiveModel::Model
include ActiveModel::Attributes
attribute :plans, array: true, default: -> { [] }
# attribute :benefit_descs, :hash, default: -> { {} }
PLAN_COLORS = ['atmosphere', 'copper', 'bluemana', 'bronze', 'cobalt', 'verdigris']
attr_accessor :id_card_templates
attr_accessor :id_card_template_benefits
attr_accessor :benefit_descs
# attribute :plans, array: true, default: []
attribute :plans, array: true, default: -> { [new_plan] }
attribute :pl_plan_key, :string
attribute :number_of_plans, :integer
attribute :benefit_descs, hash: true, default: -> { new_plan }
attr_accessor :plan_templates
attr_accessor :benefits_template
validates :plans, presence: true
# validates :benefit_descs, presence: true
validates :benefit_descs, presence: true
def initialize(params = {})
if params.present?
params = permitted_params(params)
end
super(params)
@id_card_templates = IdCardBenefitsTemplate.where.not(title: "BLANK")
@id_card_template_benefits = IdCardBenefitsTemplate.find_by(title: "BLANK").id_card_benefits.sort_by(&:sequence)
@plan_templates = IdCardBenefitsTemplate.where.not(title: "BLANK")
@benefits_template = IdCardBenefitsTemplate.find_by(title: "BLANK").id_card_benefits.sort_by(&:sequence)
# if attributes.present? && attributes[:plans].present?
# self.plans = Array(attributes[:plans])
# else
# self.plans = [new_plan]
# end
end
# def benefit_descs
# @benefit_descs ||= {}
# def plans_attributes=(attributes)
# self.plans = attributes.values.map { |plan_attrs| Plan.new(plan_attrs) }
# end
def save(pl_plan_key)
def persisted?
false
end
# The core method to initialize the array with a single blank item.
def ensure_one_plan_exists
if plans.empty?
self.plans << PlanForm.new
self.plans << PlanForm.new
end
end
def bulild_descs_plan
self.benefit_descs = IdCardBenefitsTemplate.find_by(title: "BLANK").id_card_benefits.sort_by(&:sequence)
end
def self.new_plan
plan = {}
self.permited_plans_keys.each do |key|
plan[key] = ""
end
plan
end
def permitted_params(params)
params.require(:employer_setup_plans_form).permit(
:pl_plan_key,
plans: self.permited_plans_keys,
benefit_descs: self.permited_plans_keys
)
end
def pull_from_employer_setup_form(attributes = {})
if attributes['pl_plan_key']
self.pl_plan_key = attributes['pl_plan_key']
end
if attributes['number_of_plans']
self.number_of_plans = attributes['number_of_plans']
end
end
# def form_strong_params(attributes)
# attributes.require(:employer_setup_plans_form).permit(
# plans: permited_plans_keys,
# benefit_descs: benefit_sequence_keys
# )
# end
def self.permited_plans_keys
(1..14).map { |i| "benefit_#{i}".to_sym }.push(:plan_id)
end
def permited_plans_keys
(1..14).map { |i| "benefit_#{i}".to_sym }.push(:plan_id)
end
def save
# Implement logic to save data to models after all steps are complete
# For example, create a User record with the collected data
if valid?
plans.each do |plan|
plan_id = plan.delete(:plan_id)
plan.each do |key, value|
Vhcs::HLEgglestonCardBenefit.create(
plan_info = plan.last
plan_id = plan_info.delete(:plan_id).to_i
plan_info.each do |key, value|
sequence = key.delete_prefix("benefit_").to_i
Vhcs::HlEgglestonCardBenefit.create(
plan_id: plan_id,
benefit_desc: benefit_descs["#{key}"],
benefit: value,
sequence: key,
sequence: sequence,
plan_key: pl_plan_key
)
end
@@ -47,3 +118,31 @@ class EmployerSetupPlansForm
end
end
class PlanForm
include ActiveModel::Model
include ActiveModel::Attributes
attribute :plan_id, :string
def initialize(attributes = {})
self.generate_attributes(14, "benefit_")
super(attributes)
end
def persisted?
false
end
def generate_attributes(count, prefix)
count.times do |i|
# attr_accessor :"#{prefix}#{i + 1}"
self.class.attribute "#{prefix}#{i + 1}".to_sym, :string
end
end
end
# dynamic_attribute_names.each do |attr_name|
# # Define each attribute as a String type (you can customize the type)
# self.class.attribute attr_name.to_sym, :string
# end
+5 -1
View File
@@ -1,5 +1,9 @@
// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
import "@hotwired/turbo-rails"
import "controllers"
import "trix"
import "@rails/actiontext"
import { Application } from "@hotwired/stimulus"
import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading"
const application = Application.start()
eagerLoadControllersFrom("controllers", application)
@@ -0,0 +1,32 @@
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static values = {
formColor: { type: Array, default: [] } // Declares 'items' as an Array value
}
static targets = ["template", "container", "networkLogo", "button"]
add(event) {
event.preventDefault()
event.stopPropagation()
const content = this.#updateTemplateNetwork()
this.buttonTarget.insertAdjacentHTML('beforebegin', content);
// this.containerTarget.insertAdjacentHTML("beforeend", content)
}
#updateTemplateNetwork() {
const nextIndex = this.networkLogoTargets.length
const num_of_colors = this.formColorValue.length
let colorIndex = 0
if (nextIndex != 0) {
colorIndex = nextIndex % num_of_colors
}
const newColor = this.formColorValue[colorIndex]
return this.templateTarget.innerHTML
.replace(/NEW_RECORD/g, nextIndex)
.replace(/NEXT_COLOR/g, newColor)
}
}
@@ -0,0 +1,20 @@
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["template", "container"]
connect() {
console.log("connect")
}
add(event) {
console.log("start")
event.preventDefault()
event.stopPropagation()
const content = this.templateTarget.innerHTML.replace(/NEW_EXC_RECORD/g, new Date().getTime())
this.containerTarget.insertAdjacentHTML("beforeend", content)
console.log("end")
}
}
@@ -0,0 +1,34 @@
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static values = {
formColor: { type: Array, default: [] } // Declares 'items' as an Array value
}
static targets = ["template", "container", "plan", "button"]
add(event) {
event.preventDefault()
event.stopPropagation()
const content = this.#updateTemplatePlan()
this.buttonTarget.insertAdjacentHTML("beforebegin", content)
}
#updateTemplatePlan() {
const nextIndex = this.planTargets.length
const num_of_colors = this.formColorValue.length
let colorIndex = 0
if (nextIndex != 0) {
colorIndex = nextIndex % num_of_colors
}
const newColor = this.formColorValue[colorIndex]
return this.templateTarget.innerHTML
.replace(/NEW_RECORD/g, nextIndex)
.replace(/NEW_PLAN/g, nextIndex + 1)
.replace(/NEXT_COLOR/g, newColor)
}
}
@@ -2,7 +2,10 @@ import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
static values = { url: String };
static targets = ["benefit_1", "benefit_2", "benefit_3", "benefit_4", "benefit_5", "benefit_6", "benefit_7", "benefit_8", "benefit_9", "benefit_10", "benefit_11", "benefit_12", "benefit_13", "benefit_14"];
static targets = ["benefit"];
connect() {
}
async fetchData(event) {
const templateId = event.target.value;
@@ -11,25 +14,27 @@ export default class extends Controller {
return;
}
const url = "/id_card_benefits_templates/get_templates_benefits/:id".replace(':id', templateId);
const url = `/id_card_benefits_templates/get_template_benefits/${templateId}`
const response = await fetch(url);
const templateBenefitsData = await response.json();
this.nameTarget.value = templateData.name;
this.descriptionTarget.value = templateData.description;
this.#updateFields(templateBenefitsData)
}
clearFields() {
this.nameTarget.value = '';
this.descriptionTarget.value = '';
}
updateFields(templateBenefitsData) {
templateBenefitsData.forEach(function(benefit) {
const propertyName = `benefit_${benefit.sequence}`
this[propertyName].value = benefit.benefit
async #updateFields(templateBenefitsData) {
const benefitTargetsList = this.benefitTargets
templateBenefitsData.forEach(function(bene) {
const targetElement = benefitTargetsList.find(
(element) => element.dataset.sequence == bene.sequence
);
if (targetElement) {
targetElement.value = bene.benefit;
} else {
console.error(`Target not found for sequence: ${bene.sequence}`);
}
});
}
}
+21
View File
@@ -0,0 +1,21 @@
module BrittonWeb
class Employers < BrittonWebRecord
# self.table_name = 'employers'
alias_attribute :id, :id
alias_attribute :name, :name
alias_attribute :pl_plan_key, :pl_plan_key
alias_attribute :plan_id, :plan_id
alias_attribute :dental_plan, :dental_plan
alias_attribute :single_card_template, :single_card_template
alias_attribute :multiple_card_template, :multiple_card_template
alias_attribute :logo, :logo
alias_attribute :active, :active
alias_attribute :broker_id, :broker_id
alias_attribute :created_at, :created_at
alias_attribute :updated_at, :updated_at
end
end
+17
View File
@@ -0,0 +1,17 @@
module BrittonWeb
class NetworkLogos < BrittonWebRecord
self.table_name = 'network_logos'
alias_attribute :id, :id
alias_attribute :net_logo, :net_logo
alias_attribute :exception_type, :exception_type
alias_attribute :exception_value, :exception_value
alias_attribute :default, :default
alias_attribute :employer_id, :employer_id
alias_attribute :created_at, :created_at
alias_attribute :updated_at, :updated_at
end
end
+4
View File
@@ -0,0 +1,4 @@
class BrittonWebRecord < ActiveRecord::Base
self.abstract_class = true
connects_to database: { writing: :britton_web, reading: :britton_web }
end
+3
View File
@@ -0,0 +1,3 @@
class EmployerSetupProcess < ApplicationRecord
has_many :plans
end
+17
View File
@@ -0,0 +1,17 @@
class Plan < ApplicationRecord
belongs_to :employer_setup_process
has_many :plan_benefits
after_create :create_default_benefits
private
def create_default_benefits
benefits = IdCardBenefitsTemplate.find_by(title: "BLANK").id_card_benefits.sort_by(&:sequence)
benefits.each do |ben|
plan_benefits.create(benefit_desc: ben.benefit_desc, sequence: ben.sequence)
end
end
end
+3
View File
@@ -0,0 +1,3 @@
class PlanBenefit < ApplicationRecord
belongs_to :plan
end
+1 -1
View File
@@ -1,4 +1,4 @@
module VHCS
module Vhcs
class HlPlanCode < VhcsRecord
self.table_name = 'HlPlanCode'
+1 -1
View File
@@ -1,5 +1,5 @@
module Vhcs
class HLRXCrosRef < VhcsRecord
class HlrxCrosRef < VhcsRecord
self.table_name = 'HLRXCrosRef'
-1
View File
@@ -1,5 +1,4 @@
class VhcsRecord < ActiveRecord::Base
self.abstract_class = true
# establish_connection :vhcs
connects_to database: { writing: :vhcs, reading: :vhcs }
end
+156
View File
@@ -0,0 +1,156 @@
class BenefitsWordDocProcessor
def initialize(word_doc, process=nil)
@word_doc = word_doc
if process
@process = process
else
@process = EmployerSetupProcess.new
end
end
def call
doc = Docx::Document.open(@word_doc)
index = 40
general_information = doc.paragraphs.slice(0, index)
plan_information = doc.paragraphs.slice(index + 1..)
general_fields(general_information)
plans(plan_information)
logo
@process
end
private
def general_fields(general_information)
fields = ['Group Number:', 'Employer Name:', 'Group Effective Date:']
general_information.each do |gi|
field_string = gi.to_s
if field_string.include?('Group Number:')
value = field_string.delete_prefix('Group Number:').strip
@process.group_number = value
elsif field_string.include?('Employer Name:')
value = field_string.delete_prefix('Employer Name:').strip
@process.employer_name = value
elsif field_string.include?('Group Effective Date:')
value = field_string.delete_prefix('Group Effective Date:').strip
@process.effect_date = value
end
end
end
def logo
extracted_images = []
Zip::File.open(@word_doc) do |zip_file|
zip_file.each do |entry|
if entry.name.start_with?('word/media/') && !entry.directory?
filename = File.basename(entry.name)
image_data = entry.get_input_stream.read
extracted_images << { filename: filename, data: image_data }
end
end
end
if extracted_images.length > 1
@process.logo_filename = extracted_images.last[:filename]
end
end
def plans(plan_information)
plans_array = []
plan_information.each_with_index do |pin, i|
if pin.to_s.match?(/\d*\.?\d+k/i)
new_plan = {title: pin.to_s.strip, start_index: i, benefits: []}
plans_array.push(new_plan)
end
end
plans_array.each do |pl|
new_plan = Plan.create(title: pl[:title], employer_setup_process: @process)
plan_fields = plan_information.slice(pl[:start_index] + 1, 14)
plan_fields.each_with_index do |pf, i|
field_string = pf.to_s
if field_string.strip.length > 1
case field_string
when ->(string) { string.include?("Physician Visit") }
value = field_string.delete_prefix("Physician Visit")
new_benefit = new_plan.plan_benefits.find_by(benefit_desc: "Primary Visit")
new_benefit.benefit = value
new_benefit.save
when ->(string) { string.include?("Specialist Visit") }
value = field_string.delete_prefix("Specialist Visit")
new_benefit = new_plan.plan_benefits.find_by(benefit_desc: "Specialist Visit")
new_benefit.benefit = value
new_benefit.save
when ->(string) { string.include?("Urgent Care") }
value = field_string.delete_prefix("Urgent Care")
new_benefit = new_plan.plan_benefits.find_by(benefit_desc: "Urgent Care")
new_benefit.benefit = value
new_benefit.save
when ->(string) { string.include?("Individual Deductible (in network )") }
value = field_string.delete_prefix("Individual Deductible (in network )")
new_benefit = new_plan.plan_benefits.find_by(benefit_desc: "INNInd Ded")
new_benefit.benefit = value
new_benefit.save
when ->(string) { string.include?("Family Deductible(in network )") }
value = field_string.delete_prefix("Family Deductible(in network )")
new_benefit = new_plan.plan_benefits.find_by(benefit_desc: "INNFamily Ded")
new_benefit.benefit = value
new_benefit.save
when ->(string) { string.include?("Individual Deductible (out of network)") }
value = field_string.delete_prefix("Individual Deductible (out of network)")
new_benefit = new_plan.plan_benefits.find_by(benefit_desc: "OONInd Ded")
new_benefit.benefit = value
new_benefit.save
when ->(string) { string.include?("Family Deductible (out of network) ") }
value = field_string.delete_prefix("Family Deductible (out of network) ")
new_benefit = new_plan.plan_benefits.find_by(benefit_desc: "OONFamily Ded")
new_benefit.benefit = value
new_benefit.save
when ->(string) { string.include?("Co-Insurance") }
value = field_string.delete_prefix("Co-Insurance")
new_benefit = new_plan.plan_benefits.find_by(benefit_desc: "Co-Insurance")
new_benefit.benefit = value
new_benefit.save
when ->(string) { string.include?("Out-of-Pocket(in network) ") }
value = field_string.delete_prefix("Out-of-Pocket(in network) ")
new_benefit = new_plan.plan_benefits.find_by(benefit_desc: "INNInd OOP")
new_benefit.benefit = value
new_benefit.save
when ->(string) { string.include?("Out-of-Pocket Family(in network) ") }
value = field_string.delete_prefix("Out-of-Pocket Family(in network) ")
new_benefit = new_plan.plan_benefits.find_by(benefit_desc: "INNFamily OOP")
new_benefit.benefit = value
new_benefit.save
when ->(string) { string.include?("Out-of-Pocket(out of network) ") }
value = field_string.delete_prefix("Out-of-Pocket(out of network) ")
new_benefit = new_plan.plan_benefits.find_by(benefit_desc: "OONInd OOP")
new_benefit.benefit = value
new_benefit.save
when ->(string) { string.include?("Out-of-Pocket Family (out of network) ") }
value = field_string.delete_prefix("Out-of-Pocket Family (out of network) ")
new_benefit = new_plan.plan_benefits.find_by(benefit_desc: "OONFamily OOP")
new_benefit.benefit = value
new_benefit.save
when ->(string) { string.include?("Emergency Room ") }
value = field_string.delete_prefix("Emergency Room ")
new_benefit = new_plan.plan_benefits.find_by(benefit_desc: "Emergency Room")
new_benefit.benefit = value
new_benefit.save
when ->(string) { string.include?("Preventive Care") }
value = field_string.delete_prefix("Preventive Care")
new_benefit = new_plan.plan_benefits.find_by(benefit_desc: "Preventive Care")
new_benefit.benefit = value
new_benefit.save
end
end
end
end
end
end
+1 -5
View File
@@ -6,13 +6,9 @@ class ArrayOfItemsType < ActiveModel::Type::Value
Array.wrap(value).map do |item_data|
# Assuming item_data is a hash, this creates an instance of the Item class.
# You can modify this part to match your object's initializer.
if item_data.is_a?(Hash)
Item.new(item_data)
else
item_data # Return the item as-is if it's already an object
end
end
end
# This method is used when defining the type to convert it to a string for serialization.
def serialize(value)
@@ -20,4 +16,4 @@ class ArrayOfItemsType < ActiveModel::Type::Value
end
end
ActiveModel::Type.register(:array_of_items, ArrayOfItemsType)
# ActiveModel::Type.register(:array_of_items, ArrayOfItemsType)
@@ -10,9 +10,6 @@
<div class="w-1/5">
<%= f.text_field :group_number, label: { text: "Group/Medical Number" }, class: "w-full" %>
</div>
<div>
<%= f.check_box :dental %>
</div>
</div>
<div class="flex space-x-10">
<div class="w-1/5">
@@ -23,15 +20,9 @@
</div>
</div>
<div class="flex space-x-10">
<div class="w-1/5">
<%= f.select :number_of_plans, options_for_select((1..6).to_a), label: { text: "Number of Plans" }, class: "w-1/3" %>
</div>
<div class="w-1/5">
<%= f.select :network, options_for_select([["Cigna", "cig"], ["Cigna+Regional", "cig+"], ["Medcost", "med"]]), label: { text: "Provider Network" }, data: { controller: "form-toggle", action: "change->form-toggle#toggleDivs" }, class: "w-full" %>
</div>
<div id="div-a" class="w-1/5" data-form-toggle-target="divA">
<%= f.select :number_of_additional_network_logos, options_for_select((0..6).to_a), label: { text: "Number of Additional Network Logos" }, class: "w-1/3" %>
</div>
</div>
<div class="flex space-x-5 items-center mt-4">
<label for="file_upload_input" class="cursor-pointer bg-atmosphere hover:bg-bluetang text-platinum font-bold py-2 px-4 rounded border border-platinum">
@@ -0,0 +1,64 @@
<div class="min-h-screen w-full flex flex-col" data-controller="add-alt-network-logo" data-add-alt-network-logo-form-color-value="<%= EmployerSetupPlansForm::PLAN_COLORS.to_json %>">
<h1 class="font-bold text-4xl text-platinum">New Employer Setup</h1>
<h3 class="font-bold text-2xl text-bluemana">Provider Network</h3>
<%= form_with model: @form, url: employer_setup_index_path, local: true do |f| %>
<div class="flex w-full justify-start">
<div class="flex flex-wrap w-full" data-add-alt-network-logo-target="container">
<%= button_tag "Add a Regional Logo", class: "cursor-pointer text-lg font-medium py-2 px-4 rounded w-1/7 h-75 my-8 text-[#E0E0E0] rounded-lg border border-[#C2C2C2] hover:shadow-[0_0_10px_3px_#93c5fd]", data: { action: "add-alt-network-logo#add", add_alt_network_logo_target: "button" } %>
</div>
</div>
<div class="py-10">
<%= f.submit "Continue to Summary" %>
</div>
<template data-add-alt-network-logo-target="template">
<%= f.fields_for :network_exceptions, index: 'NEW_RECORD' do |network_fields| %>
<div class="flex flex-col my-8 mr-3 space-y-6 px-3" data-controller="add-network-exception">
<div class="flex space-x-5 items-center mt-4">
<label for="file_upload_input_NEW_RECORD" class="cursor-pointer bg-NEXT_COLOR hover:bg-NEXT_COLOR-tinted text-platinum font-bold py-2 px-4 rounded border border-platinum">
Choose Network Logo File
</label>
<span id="file_name_display_NEW_RECORD" class="ml-2 text-NEXT_COLOR font-semibold">No file chosen</span>
<%= network_fields.file_field :network_logo, class: "hidden", id: "file_upload_input_NEW_RECORD", data: { add_alt_network_logo_target: "networkLogo" } %>
</div>
<%= network_fields.fields_for :exceptions, index: 0 do |exception_fields| %>
<div class="flex space-x-6 w-full">
<div class="w-full">
<%= exception_fields.select :type, options_for_select(["Zip","State"]), label: { text: "Exception Type" }, prompt: "Select Type", class: "w-full" %>
</div>
<div class="w-full">
<%= exception_fields.text_field :value, label: { text: "Exception Value" }, class: "w-full" %>
</div>
</div>
<% end %>
<div class="flex flex-col w-full space-y-6" data-add-network-exception-target="container"></div>
<%= button_tag "Add an exception rule", class: "cursor-pointer bg-NEXT_COLOR hover:bg-NEXT_COLOR-tinted text-platinum text-lg font-bold py-2 px-4 rounded border border-platinum w-full", data: { action: "add-network-exception#add" } %>
<template data-add-network-exception-target="template">
<%= network_fields.fields_for :exceptions, index: 'NEW_EXC_RECORD' do |exception_fields| %>
<div class="flex space-x-6 w-full">
<div class="w-full">
<%= exception_fields.select :type, options_for_select(["Zip","State"]), label: { text: "Exception Type" }, prompt: "Select Type", class: "w-full" %>
</div>
<div class="w-full">
<%= exception_fields.text_field :value, label: { text: "Exception Value" }, class: "w-full" %>
</div>
</div>
<% end %>
</template>
</div>
<% end %>
</template>
<% end %>
</div>
<script>
const logoButtons = document.querySelectorAll('[id^="file_upload_input_"]');
logoButtons.forEach(button => {
button.addEventListener('change', function(e) {
var fileName = e.target.files[0] ? e.target.files[0].name : 'No file chosen';
var targetIndex = e.target.id.slice(-1);
document.getElementById(`file_name_display_${targetIndex}`).textContent = fileName;
});
})
</script>
@@ -1,41 +0,0 @@
<div class="bg-deepcove min-h-screen w-full flex flex-col">
<h1 class="font-bold text-4xl text-platinum">New Employer Setup</h1>
<h3 class="font-bold text-2xl text-bluemana">Provider Network</h3>
<%= form_with model: @form, url: employer_setup_index_path, local: true do |f| %>
<% @form.number_of_additional_network_logos.to_i.times do |i| %>
<%= f.fields_for :network_exceptions do |network_fields| %>
<div class="w-full flex flex-col my-8 space-y-6">
<div class="flex space-x-5 items-center mt-4">
<label for="file_upload_input" class="cursor-pointer bg-atmosphere hover:bg-bluetang text-platinum font-bold py-2 px-4 rounded border border-platinum">
Choose Network Logo File
</label>
<span id="file_name_display" class="ml-2 text-bluemana font-semibold">No file chosen</span>
<%= network_fields.file_field :network_logo, class: "hidden", id: "file_upload_input" %>
</div>
<% 2.to_i.times do |j| %>
<%= network_fields.fields_for :exceptions do |exception_fields| %>
<div class="flex space-x-10">
<div class="w-1/5">
<%= exception_fields.select :type, options_for_select(["Zipcode","State"]), label: { text: "Exception Type" }, prompt: "Select Type", class: "w-full" %>
</div>
<div class="w-1/5">
<%= exception_fields.text_field :value, label: { text: "Exception Value" }, class: "w-full" %>
</div>
</div>
<% end %>
<% end %>
</div>
<% end %>
<% end %>
<div class="py-10">
<%= f.submit "Continue to Summary" %>
</div>
<% end %>
</div>
<script>
document.getElementById('file_upload_input').addEventListener('change', function(e) {
var fileName = e.target.files[0] ? e.target.files[0].name : 'No file chosen';
document.getElementById('file_name_display').textContent = fileName;
});
</script>
@@ -1,38 +0,0 @@
<div class="bg-deepcove min-h-screen w-full flex flex-col">
<h1 class="font-bold text-4xl text-platinum">New Employer Setup</h1>
<%= form_with url: 'create_plans', method: :post do |form| %>
<div class="w-full flex">
<div class="flex flex-col mr-4">
<% @id_card_template_benefits.each do |bene| %>
<div>
<%= form.text_field "plans[benefit_descs][#{bene.sequence}]", label: { text: "Benefit Description" }, value: "#{bene.benefit_desc}" %>
</div>
<% end %>
</div>
<% @employer_data['employer']['number_of_plans'].to_i.times do |i| %>
<div class="flex flex-col">
<div>
<%= form.text_field "plans[plan_#{i}][plan_id]", label: { text: "Plan Id" } %>
</div>
<div class="bg-gray-200 rounded py-2 px-4 text-bluetang font-semibold leading-tight">
<select data-action="benefits-template-picker#fetchData" data-benefits-template-picker-url-value="/id_card_benefits_templates/get_templates_benefits/:id">
<option value="">Select Existing Template (optional)</option>
<% @id_card_templates.each do |temp| %>
<option value="<%= temp.id %>"><%= temp.name %></option>
<% end %>
</select>
</div>
<% @id_card_template_benefits.each do |bene| %>
<div>
<div>
<%= form.text_field "plans[plan_#{i}][#{bene.sequence}]", label: { text: "Benefit Value" }, data: { benefits_template_picker_target: "benefit_#{bene.sequence}" } %>
</div>
</div>
<% end %>
</div>
<% end %>
</div>
<%= form.submit "Summary" %>
</div>
<% end %>
</div>
+43 -17
View File
@@ -1,43 +1,69 @@
<div class="bg-deepcove min-h-screen w-full flex flex-col">
<div class="min-h-screen w-full flex flex-col" data-controller="add-plan" data-add-plan-form-color-value="<%= EmployerSetupPlansForm::PLAN_COLORS.to_json %>">
<h1 class="font-bold text-4xl text-platinum">New Employer Setup</h1>
<h3 class="font-bold text-2xl text-bluemana">Medical Plans</h3>
<div class="flex flex-col pl-6">
<%= form_with model: @form, url: employer_setup_index_path, local: true do |f| %>
<%= f.text_field :pl_plan_key, label: { text: "Employer PL Plan Key" }, class: "justify-self-start" %>
<div class="w-full flex my-8">
<div class="flex flex-col justify-end pr-6">
<% @id_card_template_benefits.each do |bene| %>
<%= f.fields_for :benefit_descs do |bd_fields| %>
<div class="flex flex-wrap w-full" data-add-plan-target="container">
<div class="flex flex-col items-stretch justify-end pr-6 pl-1 w-1/4">
<%= f.fields_for :benefit_descs do |plan_benefit_fields| %>
<%= plan_benefit_fields.text_field :plan_id, class: "hidden", value: "descriptions" %>
<% @form.benefits_template.each do |bene| %>
<div>
<%= bd_fields.text_field "#{bene.sequence}", label: { text: "Benefit Description #{bene.sequence}" }, value: "#{bene.benefit_desc}" %>
<%= plan_benefit_fields.text_field "benefit_#{bene.sequence}", label: { text: "Benefit Description #{bene.sequence}" }, value: "#{bene.benefit_desc}", class: "w-full" %>
</div>
<% end %>
<% end %>
</div>
<% @form.number_of_plans.to_i.times do |i| %>
<% border_colors = ['border-atmosphere', 'border-copper', 'border-bluemana'] %>
<% text_colors = ['text-atmosphere', 'text-copper', 'text-bluemana'] %>
<div class="inline-flex flex-col justify-end pr-6 pl-1 relative">
<div class="absolute left-0 top-[2%] h-[98%] border-l-4 <%= border_colors[i] %> rounded-bl-lg"></div>
<div class="font-bold text-2xl <%= text_colors[i] %> -ml-[6px] z-2 w-full">
<% @form.plans.each_with_index do |plan, i| %>
<div class="inline-flex flex-col justify-end pr-6 pl-1 mt-10 relative w-1/4" data-controller="benefits-template-picker">
<div class="absolute left-0 top-[2%] h-[98%] border-l-4 <%= "border-#{EmployerSetupPlansForm::PLAN_COLORS[i]}" %> rounded-bl-lg"></div>
<div class="font-bold text-2xl <%= "text-#{EmployerSetupPlansForm::PLAN_COLORS[i]}" %> -ml-[6px] z-2 w-full">
<%= "Plan #{i + 1}" %>
</div>
<%= f.fields_for :plans do |plan_fields| %>
<%= f.fields_for :plans, index: i do |plan_fields| %>
<div class="pl-1 w-full">
<%= plan_fields.text_field :plan_id, label: { text: "Plan Id" }, class: "w-full" %>
<%= plan_fields.text_field :plan_id, label: { text: "Plan Id" }, class: "w-full", data: { add_plan_target: "plan" } %>
</div>
<div class="pl-1" data-controller="benefits_template_picker_controller">
<%= f.select :template_id, options_from_collection_for_select(@id_card_templates, :id, :name), { prompt: "Select Existing Template (optional)", data: { action: "benefits-template-picker#fetchData" }} %>
<div class="pl-1">
<%= f.select :template_id, options_from_collection_for_select(@form.plan_templates, :id, :title), { prompt: "Select Plan Template" }, { data: { action: "benefits-template-picker#fetchData" }} %>
</div>
<% @id_card_template_benefits.each do |bene| %>
<% @form.benefits_template.each do |bene| %>
<div>
<div class="pl-1 w-full">
<%= plan_fields.text_field "#{bene.sequence}", label: { text: "Benefit Value #{bene.sequence}" }, data: { benefits_template_picker_target: "benefit_#{bene.sequence}" }, class: "w-full" %>
<%= plan_fields.text_field "benefit_#{bene.sequence}", label: { text: "Benefit Value #{bene.sequence}" }, data: { benefits_template_picker_target: "benefit", sequence: "#{bene.sequence}"}, class: "w-full" %>
</div>
</div>
<% end %>
<% end %>
</div>
<% end %>
<%= button_tag "Add a Plan", class: "cursor-pointer text-2xl font-bold py-2 pr-6 mt-10 w-[calc(24%-1rem)] w-1/4 min-h-[940px] text-[#E0E0E0] rounded-lg font-medium border border-[#E0E0E0] bg-[#173057] hover:bg-transparent hover:shadow-[0_0_10px_3px_#93c5fd] transition-colors duration-150", data: { action: "add-plan#add", add_plan_target: "button" } %>
<template data-add-plan-target="template">
<div class="inline-flex flex-col justify-end pr-6 pl-1 mt-10 relative w-1/4" data-controller="benefits-template-picker">
<div class="absolute left-0 top-[2%] h-[98%] border-l-4 border-NEXT_COLOR rounded-bl-lg"></div>
<div class="font-bold text-2xl text-NEXT_COLOR -ml-[6px] z-2 w-full">
<%= "Plan NEW_PLAN" %>
</div>
<%= f.fields_for :plans, index: 'NEW_RECORD' do |plan_fields| %>
<div class="pl-1 w-full">
<%= plan_fields.text_field :plan_id, label: { text: "Plan Id" }, class: "w-full", data: { add_plan_target: "plan" } %>
</div>
<div class="pl-1">
<%= f.select :template_id, options_from_collection_for_select(@form.plan_templates, :id, :title), { prompt: "Select Plan Template" }, { data: { action: "benefits-template-picker#fetchData" }} %>
</div>
<% @form.benefits_template.each do |bene| %>
<div>
<div class="pl-1 w-full">
<%= plan_fields.text_field "benefit_#{bene.sequence}", label: { text: "Benefit Value #{bene.sequence}" }, data: { benefits_template_picker_target: "benefit", sequence: "#{bene.sequence}"}, class: "w-full" %>
</div>
</div>
<% end %>
<% end %>
</div>
</template>
</div>
</div>
<div class="py-10">
<%= f.submit "Continue to Provider Network" %>
+9 -3
View File
@@ -1,7 +1,7 @@
<!DOCTYPE html>
<html>
<head>
<title>Railsondocker</title>
<title>Baclight</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
@@ -11,9 +11,15 @@
<%= javascript_importmap_tags %>
</head>
<body class="w-full flex bg-deepcove">
<main class="w-11/12 mt-28 px-5 flex">
<body>
<main>
<div class="w-full h-screen flex bg-black justify-center items-center">
<div class="h-[98%] w-[calc(100%-1rem)] mt-1 mb-2 flex justify-center items-center shadow-[0_0_10px_3px_#93c5fd] rounded-xl bg-[#04153E]">
<div class="w-11/12 mt-8 px-5 flex">
<%= yield %>
</div>
</div>
</div>
</main>
</body>
</html>
+13 -16
View File
@@ -1,17 +1,14 @@
<h1>Welcome</h1>
<%= link_to "Articles", articles_path %>
<h2>Stimulus Check</h2>
<div data-controller="hello">
<input data-hello-target="name" type="text">
<button data-action="click->hello#greet">
Greet
</button>
<span data-hello-target="output">
</span>
<div class="flex items-center justify-center h-full w-full">
<div class="flex flex-col text-7xl font-bold text-[#2A4B6F] space-y-30">
<div>
<span class="[text-shadow:0_0_20px_#fff,0_0_50px_#0090D9,0_0_80px_#0ff] text-[#04153E]">B</span>acl<span class="text-[#CD7F32]">i</span>ght
</div>
<div>
<span class="[text-shadow:0_0_20px_#fff,0_0_50px_#0090D9,0_0_80px_#0ff] text-[#04153E]">B</span>acl<span class="relative inline-block">i<span class="absolute top-0 right-0 h-3 w-3 rounded-full bg-[#CD7F32] translate-y-[7px] -translate-x-[3px]"></span></span>ght
</div>
<div>
<span class="justify-self-end [text-shadow:0_0_20px_#fff,0_0_50px_#0090D9,0_0_80px_#0ff] text-[#04153E]">B</span>acl<span class="relative inline-block">i<span class="absolute top-0 right-0 h-3 w-3 rounded-full bg-[#CD7F32] translate-y-[7px] -translate-x-[3px] shadow-[0_0_7px_2px_#93c5fd]"></span></span>ght
</div>
</div>
</div>
+1 -1
View File
@@ -2,7 +2,7 @@
require "fileutils"
APP_ROOT = File.expand_path("..", __dir__)
APP_NAME = "railsondocker"
APP_NAME = "baclight"
def system!(*args)
system(*args, exception: true)
+1 -1
View File
@@ -8,4 +8,4 @@ test:
production:
adapter: redis
url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %>
channel_prefix: railsondocker_production
channel_prefix: baclight_production
+9
View File
@@ -37,6 +37,15 @@ development:
password: BSTIBOY
database_tasks: false
tds_version: 7.3
britton_web:
<<: *default
host: 10.41.82.73
port: 1433
database: BrittonWeb
username: SA
password: Adm1nBb5
database_tasks: false
tds_version: 7.3
# The specified database role being used to connect to PostgreSQL.
# To create additional roles in PostgreSQL see `$ createuser --help`.
@@ -0,0 +1,3 @@
Rails.application.config.to_prepare do
ActiveModel::Type.register(:array_of_items, ArrayOfItemsType)
end
+1 -1
View File
@@ -2,7 +2,7 @@
Rails.application.routes.draw do
resources :employer_setup, only: [:new, :create]
get "welcome/index"
get 'id_card_benefits_templates/get_template_benefits/:id', to: 'id_card_benefits_templates#get_template_benefits'
# Reveal health status on /up that returns 200 if the app boots with no exceptions, otherwise 500.
# Can be used by load balancers and uptime monitors to verify that the app is live.
@@ -0,0 +1,16 @@
class CreateEmployerSetupProcesses < ActiveRecord::Migration[7.2]
def change
create_table :employer_setup_processes do |t|
t.string :employer_name
t.string :group_number
t.string :effect_date
t.string :logo_filename
t.string :form_method
t.string :status
t.string :current_step
t.timestamps
end
end
end
+11
View File
@@ -0,0 +1,11 @@
class CreatePlans < ActiveRecord::Migration[7.2]
def change
create_table :plans do |t|
t.string :title
t.references :employer_setup_process, null: false, foreign_key: true
t.timestamps
end
end
end
@@ -0,0 +1,12 @@
class CreatePlanBenefits < ActiveRecord::Migration[7.2]
def change
create_table :plan_benefits do |t|
t.string :benefit_desc
t.string :benefit
t.integer :sequence
t.references :plan, null: false, foreign_key: true
t.timestamps
end
end
end
+33 -1
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: 2025_11_04_171752) do
ActiveRecord::Schema[7.2].define(version: 2025_12_02_142512) do
create_table "action_text_rich_texts", force: :cascade do |t|
t.string "name", null: false
t.text "body"
@@ -49,6 +49,18 @@ ActiveRecord::Schema[7.2].define(version: 2025_11_04_171752) do
t.index ["blob_id", "variation_digest"], name: "index_active_storage_variant_records_uniqueness", unique: true
end
create_table "employer_setup_processes", force: :cascade do |t|
t.string "employer_name"
t.string "group_number"
t.string "effect_date"
t.string "logo_filename"
t.string "form_method"
t.string "status"
t.string "current_step"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
create_table "id_card_benefits", force: :cascade do |t|
t.string "benefit_desc"
t.string "benefit"
@@ -65,7 +77,27 @@ ActiveRecord::Schema[7.2].define(version: 2025_11_04_171752) do
t.datetime "updated_at", null: false
end
create_table "plan_benefits", force: :cascade do |t|
t.string "benefit_desc"
t.string "benefit"
t.integer "sequence"
t.bigint "plan_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["plan_id"], name: "index_plan_benefits_on_plan_id"
end
create_table "plans", force: :cascade do |t|
t.string "title"
t.bigint "employer_setup_process_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["employer_setup_process_id"], name: "index_plans_on_employer_setup_process_id"
end
add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id"
add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id"
add_foreign_key "id_card_benefits", "id_card_benefits_templates"
add_foreign_key "plan_benefits", "plans"
add_foreign_key "plans", "employer_setup_processes"
end
+2 -1
View File
@@ -16,7 +16,8 @@ RUN --mount=type=cache,target=/var/cache/apt \
tdsodbc \
freetds-dev \
libvips \
libpq-dev
libpq-dev \
libyaml-dev
ENV LANG=C.UTF-8 \
BUNDLE_JOBS=4 \
@@ -9,6 +9,10 @@ class LegacyDbModelGenerator < Rails::Generators::Base
@db_record = 'VhcsRecord'.constantize
@module = 'Vhcs'.constantize
@file_folder = 'vhcs'
elsif db_name == 'BrittonWeb'
@db_record = 'BrittonWebRecord'.constantize
@module = 'BrittonWeb'.constantize
@file_folder = 'britton_web'
elsif db_name == 'HEBWeb'
@db_record = 'WebRecord'.constantize
@module = 'HebWeb'.constantize