Init dump

This commit is contained in:
Jason Jordan
2025-11-24 08:22:44 -05:00
parent d48bb96791
commit 3fbece7da6
73 changed files with 1747 additions and 121 deletions
View File
+1
View File
@@ -2,3 +2,4 @@
//= link_directory ../stylesheets .css
//= link_tree ../../javascript .js
//= link_tree ../../../vendor/javascript .js
//= link_tree ../builds
+18
View File
@@ -0,0 +1,18 @@
@import "tailwindcss";
@theme {
/* dark blue */
--color-deepcove: #04153E;
/* medium dark blue */
--color-bluetang: #2A4B6F;
/* bright blue */
--color-atmosphere: #0096E0;
/* light blue */
--color-bluemana: #6AC8F1;
/* platinum */
--color-platinum: #E0E0E0;
/* copper */
--color-copper: #B06E30;
/* bronze */
--color-bronze: #D38F4A;
}
@@ -0,0 +1,191 @@
class EmployerSetupController < ApplicationController
def new
@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'
@form = @top_form
end
render @top_form.current_step_view
end
def create
@top_form = EmployerSetupForm.new(session[:employer_setup_data])
if @top_form.current_step != 'summary'
if process_step(@top_form.current_step)
session[:employer_setup_data]['current_step'] = @top_form.next_step
redirect_to new_employer_setup_path
else
render @top_form.current_step_view
end
else
if @top_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
@form = RegistrationForm.new(registration_params)
if params[:back_button]
@form.current_step = @form.previous_step
elsif params[:skip_newsletter]
@form.current_step = @form.next_step # Skip newsletter step
end
render :new
end
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 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]],
)
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
session[:employer_setup_data]['current_step'] = @top_form.next_step
redirect_to new_employer_setup_path
else
render @top_form.current_step_view
end
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 employer_setup_params
# params.require(:employer_setup_form).permit(
# :current_step,
# :name,
# :employer_logo,
# :group_number,
# :pl_plan_key,
# :effect_date,
# :number_of_plans,
# :network,
# :number_of_additional_network_logos,
# network_exceptions: [:network_logo, exceptions: [:type, :value]],
# plans: permited_plans_keys,
# benefit_descs: benefit_sequence_keys
# )
# 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 plans_params
# plans_keys = params[:plans]&.keys || []
# plans_keys.each_with_object({}) do |key, hash|
# if key == 'benefit_descs' || key.match?(/^plan_\d$/)
# hash[key.to_sym] = permited_plan_param_list
# end
# end
# end
# def permited_plan_param_list
# (1..14).map { |i| i.to_s.to_sym }.push(:plan_id)
# end
end
@@ -0,0 +1,109 @@
class EmployerSetupController < ApplicationController
def new
@employer_data = session[:employer_data] || {}
# @id_card_templates = IdCardTemplate.where.not(title: "BLANK")
# @id_card_template_benefits = IdCardTemplate.find_by(title: "BLANK").id_card_template_benefits.sort_by(&:sequence)
end
def create_employer
@employer_data = {employer: {}}
@employer_data[:employer].merge!(params.require(:employer).permit(
:name,
:group_number,
:pl_plan_key,
:effect_date
))
@employer_data[:employer].merge!(params.permit(:number_of_plans))
session[:employer_data] = @employer_data
puts session[:employer_data]
redirect_to action: :plans
end
def plans
@employer_data = session[:employer_data] || {}
@id_card_templates = IdCardBenefitsTemplate.where.not(title: "BLANK")
@id_card_template_benefits = IdCardBenefitsTemplate.find_by(title: "BLANK").id_card_benefits.sort_by(&:sequence)
end
def create_plans
@employer_data = session[:employer_data] || {}
@employer_data.merge!(params.require(:plans).permit(plans_params))
session[:employer_data] = @employer_data
redirect_to action: :networks
end
def networks
@employer_data = session[:employer_data] || {}
end
def create_provider_networks
@employer_data = session[:employer_data] || {}
@employer_data.merge!(params.require(:plans).permit(plans_params))
session[:employer_data] = @employer_data
redirect_to action: :networks
end
def process_bad_name
@final_data = session[:employer_data]
# Vhcs::HlPlanCode.create(
# group_number: @final_data['employer']['name'],
# medical_number: @final_data['employer']['group_number'],
# dental_number: ' ',
# plan_key: @final_data['employer']['pl_plan_key'],
# effect_date: @final_data['employer']['effect_date']
# )
# default = Vhcs::HLRXCrosRef.find_by(pl_plan_key: 52)
# Vhcs::HLRXCrosRef.create(
# group_no: @final_data['employer']['group_number'],
# rx_group_id: @final_data['employer']['group_number'],
# help_desk: default.help_desk,
# customer_service: default.customer_service,
# web_url: default.web_url,
# pl_plan_key: @final_data['employer']['pl_plan_key']
# )
# plans_data = @final_data['plans']
# benefit_descs = plans_data.delete('benefit_descs')
# plans_data.each do |key, value|
# plan_id = value.delete('plan_id')
# value.each do |key2, value2|
# Vhcs::HLEgglestonCardBenefit.create(
# plan_id: plan_id,
# benefit_desc: benefit_descs[key2],
# benefit: value2,
# sequence: key2,
# plan_key: @final_data['employer']['pl_plan_key']
# )
# end
# end
# Create or update your model with @final_data
# Clear the session data after successful save
session[:employer_data] = nil
# Redirect to a success page
end
private
def plans_params
plans_keys = params[:plans]&.keys || []
plans_keys.each_with_object({}) do |key, hash|
if key == 'benefit_descs' || key.match?(/^plan_\d$/)
hash[key.to_sym] = permited_plan_param_list
end
end
end
def permited_plan_param_list
(1..14).map { |i| i.to_s.to_sym }.push(:plan_id)
end
end
@@ -0,0 +1,89 @@
class EmployerSetupController < ApplicationController
def new
# session.delete(:employer_setup_data)
@form = EmployerSetupForm.new(session[:employer_setup_data])
if @form.current_step == "plans"
@id_card_templates = IdCardBenefitsTemplate.where.not(title: "BLANK")
@id_card_template_benefits = IdCardBenefitsTemplate.find_by(title: "BLANK").id_card_benefits.sort_by(&:sequence)
end
puts session[:employer_setup_data]
render "employer_setup/#{@form.current_step}" # Renders the view for the current step
end
def create
filtered_params = employer_setup_params.except(:validation_context)
@form = EmployerSetupForm.new(filtered_params)
if @form.current_step == "general" && @form.valid?(:general_info)
# @form.current_step = "plans"
@form.current_step = "networks" # TESTING, Change Back
session[:employer_setup_data] = @form.attributes.slice("current_step", "name", "employer_logo", "group_number", "pl_plan_key", "effect_date", "number_of_plans", "network", "number_of_additional_network_logos")
redirect_to new_employer_setup_path # Redirect to the next step
elsif @form.current_step == "plans" && @form.valid?(:plan_info)
if @form.number_of_additional_network_logos == 0
next_step = "summary"
else
next_step = "networks"
end
@form.current_step = next_step
session[:employer_setup_data].merge!(@form.attributes.slice("current_step", "plans", "benefit_descs"))
redirect_to new_employer_setup_path
# @form = UserOnboardingForm.new(session[:employer_setup_data]) # Re-initialize with all data
elsif @form.current_step == "networks" && @form.valid?(:network_info)
@form.current_step = "summary"
session[:employer_setup_data].merge!(@form.attributes.slice("current_step", "network_exceptions"))
redirect_to new_employer_setup_path
elsif @form.current_step == "summary"
puts @form.attributes
if @form.save
session.delete(:employer_setup_data) # Clear session data after successful save
redirect_to root_path, notice: "Employer setup successfully!"
else
render "employer_setup/summary" # Render step two again with errors
end
else
render "employer_setup/#{@form.current_step}" # Render the current step again with errors
end
end
private
def employer_setup_params
params.require(:employer_setup_form).permit(
:current_step,
:name,
:employer_logo,
:group_number,
:pl_plan_key,
:effect_date,
:number_of_plans,
:network,
:number_of_additional_network_logos,
network_exceptions: [:network_logo, exceptions: [:type, :value]],
plans: permited_plans_keys,
benefit_descs: benefit_sequence_keys
)
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 plans_params
plans_keys = params[:plans]&.keys || []
plans_keys.each_with_object({}) do |key, hash|
if key == 'benefit_descs' || key.match?(/^plan_\d$/)
hash[key.to_sym] = permited_plan_param_list
end
end
end
def permited_plan_param_list
(1..14).map { |i| i.to_s.to_sym }.push(:plan_id)
end
end
@@ -0,0 +1,89 @@
class IdCardBenefitsTemplatesController < ApplicationController
skip_before_action :verify_authenticity_token
def new_id_card_template
@id_card_templates = IdCardTemplate.where.not(title: "BLANK")
@id_card_template_benefits = IdCardTemplate.find_by(title: "BLANK").id_card_template_benefits.sort_by(&:sequence)
end
def create_id_card_template
@id_card_template = IdCardTemplate.create(title: params[:title])
params[:benefits].each do |key, value|
IdCardTemplateBenefit.create(
sequence: key,
benefit_desc: value["desc"],
benefit: value["value"],
id_card_template: @id_card_template
)
end
respond_to do |format|
if @id_card_template.save && @id_card_template.id_card_template_benefits.length == 14
format.html { redirect_to '/dev_tools/new_id_card_setup', notice: "Template was successfully created." }
# format.json { render :show, status: :created, location: @employer }
else
format.html { render :new_id_card_template, status: :unprocessable_entity }
# format.json { render json: @employer.errors, status: :unprocessable_entity }
end
end
end
def new_id_card_setup
@id_card_templates = IdCardTemplate.where.not(title: "BLANK")
@id_card_template_benefits = IdCardTemplate.find_by(title: "BLANK").id_card_template_benefits
end
def get_templates_benefits
@id_card_benefits = IdCardBenefitsTemplate.find(params[:id]).id_card_benefits
render json: @id_card_benefits.as_json
end
def create_id_card_setup
employer_general = params['general']
hl_plan_code = Vhcs::HlPlanCode.new(
group_number: employer_general['group_number'],
medical_number: employer_general['group_number'],
dental_number: '',
plan_key: employer_general['pl_plan_key'],
effect_date: employer_general['effect_date']
)
# Replace fairos_info with template like for benefits
fairos_info = Vhcs::HLRXCrosRef.where(pl_plan_key: 52).first
hlrx_cros_ref = Vhcs::HLRXCrosRef.new(
group_no: employer_general['group_number'],
rx_group_id: employer_general['group_number'],
help_desk: fairos_info.help_desk,
customer_service: fairos_info.customer_service,
web_url: fairos_info.web_url,
pl_plan_key: employer_general['pl_plan_key']
)
number_of_plans = params[:number_of_plans].to_i
number_of_plans.each do |i|
value['benefits'].each do |ben_key, ben_value|
Vhcs::HLEgglestonCardBenefit.create(
plan_id: value['plan_id'],
benefit_desc: ben_value["desc"],
benefit: ben_value["value"],
sequence: ben_key,
plan_key: employer_general['pl_plan_key']
)
end
end
respond_to do |format|
if hl_plan_code.save && hlrx_cros_ref.save
format.html { redirect_to '/dev_tools/new_id_card_setup', notice: "Card setup was successfully created." }
# format.json { render :show, status: :created, location: @employer }
else
format.html { render :new_id_card_setup, status: :unprocessable_entity }
# format.json { render json: @employer.errors, status: :unprocessable_entity }
end
end
end
end
+106
View File
@@ -0,0 +1,106 @@
class TailwindFormBuilder < ActionView::Helpers::FormBuilder
class_attribute :text_field_helpers, default: field_helpers - [:label, :check_box, :radio_button, :fields_for, :fields, :hidden_field, :file_field]
# leans on the FormBuilder class_attribute `field_helpers`
# you'll want to add a method for each of the specific helpers listed here if you want to style them
TEXT_FIELD_STYLE = "bg-gray-200 rounded py-2 px-4 text-bluetang font-semibold leading-tight focus:outline-none focus:bg-white".freeze
SELECT_FIELD_STYLE = "block bg-gray-200 text-gray-700 py-2 px-4 rounded leading-tight focus:outline-none focus:bg-white".freeze
SUBMIT_BUTTON_STYLE = "shadow bg-bronze focus:shadow-outline focus:outline-none text-white font-bold py-2 px-4 rounded hover:bg-copper".freeze
text_field_helpers.each do |field_method|
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
def #{field_method}(method, options = {})
if options.delete(:tailwindified)
super
else
text_like_field(#{field_method.inspect}, method, options)
end
end
RUBY_EVAL
end
def submit(value = nil, options = {})
custom_opts, opts = partition_custom_opts(options)
classes = apply_style_classes(SUBMIT_BUTTON_STYLE, custom_opts)
super(value, {class: classes}.merge(opts))
end
def select(method, choices = nil, options = {}, html_options = {}, &block)
custom_opts, opts = partition_custom_opts(options)
classes = apply_style_classes(SELECT_FIELD_STYLE, custom_opts, method)
labels = labels(method, custom_opts[:label], options)
field = super(method, choices, opts, html_options.merge({class: classes}), &block)
labels + field
end
private
def text_like_field(field_method, object_method, options = {})
custom_opts, opts = partition_custom_opts(options)
classes = apply_style_classes(TEXT_FIELD_STYLE, custom_opts, object_method)
field = send(field_method, object_method, {
class: classes,
title: errors_for(object_method)&.join(" ")
}.compact.merge(opts).merge({tailwindified: true}))
labels = labels(object_method, custom_opts[:label], options)
labels + field
end
def labels(object_method, label_options, field_options)
label = tailwind_label(object_method, label_options, field_options)
error_label = error_label(object_method, field_options)
@template.content_tag("div", label + error_label, {class: "flex flex-col items-start"})
end
def tailwind_label(object_method, label_options, field_options)
text, label_opts = if label_options.present?
[label_options[:text], label_options.except(:text)]
else
[nil, {}]
end
label_classes = label_opts[:class] || "block text-platinum font-bold md:text-right mb-1 md:mb-0 pr-4"
label_classes += " text-yellow-800 dark:text-yellow-400" if field_options[:disabled]
label(object_method, text, {
class: label_classes
}.merge(label_opts.except(:class)))
end
def error_label(object_method, options)
if errors_for(object_method).present?
error_message = @object.errors[object_method].collect(&:titleize).join(", ")
tailwind_label(object_method, {text: error_message, class: " font-bold text-red-500"}, options)
end
end
def border_color_classes(object_method)
if errors_for(object_method).present?
" border-2 border-red-400 focus:border-rose-200"
else
" border border-platinum focus:border-yellow-700"
end
end
def apply_style_classes(classes, custom_opts, object_method = nil)
classes + border_color_classes(object_method) + " #{custom_opts[:class]}"
end
CUSTOM_OPTS = [:label, :class].freeze
def partition_custom_opts(opts)
opts.partition { |k, v| CUSTOM_OPTS.include?(k) }.map(&:to_h)
end
def errors_for(object_method)
return unless @object.present? && object_method.present?
@object.errors[object_method]
end
end
+57
View File
@@ -0,0 +1,57 @@
class EmployerSetupForm
include ActiveModel::Model
include ActiveModel::Attributes
FIRST_STEP = "general_information"
attribute :current_step, :string, default: FIRST_STEP
attribute :general_information_data
attribute :plans_data
attribute :network_exceptions_data
def initialize(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])
end
def steps
%w[general_information plans network_exceptions summary]
end
def current_step_view
"employer_setup/#{self.current_step}"
end
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
end
end
@@ -0,0 +1,62 @@
class EmployerSetupForm
include ActiveModel::Model
include ActiveModel::Attributes
attribute :current_step, :string, default: "general"
attribute :name, :string
attribute :employer_logo
attribute :group_number, :string
attribute :pl_plan_key, :string
attribute :effect_date, :string
attribute :number_of_plans, :integer
attribute :network, :string
attribute :number_of_additional_network_logos, :integer
attribute :plans, array: true, default: -> { [] }
# attribute :benefit_descs, :hash, default: -> { {} }
attribute :network_exceptions, array: true, default: -> { [] }
attr_accessor :benefit_descs
# Define validations based on the current step
with_options on: :general_info do
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 :network, presence: true
# validates :number_of_additional_network_logos, presence: true if network = "cigna+"
end
with_options on: :plan_info do
validates :plans, presence: true
# validates :benefit_descs, presence: true
end
with_options on: :network_info do
# validates :network_exceptions, presence: true if number_of_additional_network_logos > 0
end
# 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 benefit_descs
@benefit_descs ||= {}
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? && step == total_steps
# User.create!(name: name, email: email, password: password)
true
else
false
end
end
end
@@ -0,0 +1,72 @@
class EmployerSetupGeneralInformationForm
include ActiveModel::Model
include ActiveModel::Attributes
attribute :name, :string
attribute :employer_logo
attribute :group_number, :string
attribute :dental, :boolean
attribute :pl_plan_key, :string
attribute :effect_date, :string
attribute :number_of_plans, :integer
attribute :network, :string
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 :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 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?
hl_plan_code = Vhcs::HlPlanCode.create!(
group_number: group_number,
medical_number: group_number,
dental_number: '',
plan_key: pl_plan_key,
effect_date: effect_date
)
# Replace fairos_info with template like for benefits
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,
customer_service: fairos_info.customer_service,
web_url: fairos_info.web_url,
pl_plan_key: pl_plan_key
)
web_employer = BrittonWeb::Employers.create!(
pl_plan_key: pl_plan_key,
dental_plan: dental,
single_card_template: 'FairosRxIDCard',
logo: employer_logo.filename
)
BrittonWeb::NetworkLogos.create!(
employer: web_employer,
net_logo: network,
default: true
)
true
else
false
end
end
end
@@ -0,0 +1,46 @@
class EmployerSetupNetworkExceptionsForm
include ActiveModel::Model
include ActiveModel::Attributes
Network_exception = Struct.new(:network_logo, :exceptions)
attribute :network_exceptions, :array_of_items, default: -> { [] }
# 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 save(pl_plan_key)
# 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|
BrittonWeb::NetworkLogos.create!(
employer: employer,
net_logo: ne.network_logo,
exception_type: ne.type,
exception_value: ne.value,
default: false
)
end
true
else
false
end
end
end
class NetworkException
include ActiveModel::Model
include ActiveModel::Attributes
attribute :network_logo
attribute :exceptions, array: true, default: -> { [] }
end
+49
View File
@@ -0,0 +1,49 @@
class EmployerSetupPlansForm
include ActiveModel::Model
include ActiveModel::Attributes
attribute :plans, array: true, default: -> { [] }
# attribute :benefit_descs, :hash, default: -> { {} }
attr_accessor :id_card_templates
attr_accessor :id_card_template_benefits
attr_accessor :benefit_descs
validates :plans, presence: true
# validates :benefit_descs, presence: true
def initialize(params = {})
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)
end
# def benefit_descs
# @benefit_descs ||= {}
# end
def save(pl_plan_key)
# 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_id: plan_id,
benefit_desc: benefit_descs["#{key}"],
benefit: value,
sequence: key,
plan_key: pl_plan_key
)
end
end
true
else
false
end
end
end
+2
View File
@@ -0,0 +1,2 @@
module IdCardEmployersHelper
end
-2
View File
@@ -3,5 +3,3 @@ import "@hotwired/turbo-rails"
import "controllers"
import "trix"
import "@rails/actiontext"
console.log('Hello World from application.js');
@@ -7,5 +7,3 @@ application.debug = false
window.Stimulus = application
export { application }
console.log('Hello World from controllers/application.js');
@@ -0,0 +1,38 @@
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"];
async fetchData(event) {
const templateId = event.target.value;
if (!templateId) {
this.clearFields();
return;
}
const url = "/id_card_benefits_templates/get_templates_benefits/:id".replace(':id', templateId);
const response = await fetch(url);
const templateBenefitsData = await response.json();
this.nameTarget.value = templateData.name;
this.descriptionTarget.value = templateData.description;
}
clearFields() {
this.nameTarget.value = '';
this.descriptionTarget.value = '';
}
updateFields(templateBenefitsData) {
templateBenefitsData.forEach(function(benefit) {
const propertyName = `benefit_${benefit.sequence}`
this[propertyName].value = benefit.benefit
});
}
}
// this[propertyName]
// const propertyName = `${valueName}Value`;
@@ -0,0 +1,37 @@
import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
static targets = ["numberInput", "planFieldsContainer", "template"];
connect() {
this.updatePlanFields();
}
updatePlanFields() {
const desiredCount = parseInt(this.numberInputTarget.value || 1, 10);
const currentCount = this.planFieldsContainerTarget.children.length;
if (desiredCount > currentCount) {
this.addPlanFields(desiredCount - currentCount);
} else if (desiredCount < currentCount) {
this.removePlanFields(currentCount - desiredCount);
}
}
addPlanFields(count) {
for (let i = 0; i < count; i++) {
const newPlanField = this.templateTarget.content.cloneNode(true);
// Replace '__INDEX__' with a unique value for nested attributes
// e.g., using Date.now() or a counter
const uniqueIndex = Date.now() + i;
newPlanField.innerHTML = newPlanField.innerHTML.replace(/__INDEX__/g, uniqueIndex);
this.planFieldsContainerTarget.appendChild(newPlanField);
}
}
removePlanFields(count) {
for (let i = 0; i < count; i++) {
this.planFieldsContainerTarget.lastElementChild.remove();
}
}
}
@@ -0,0 +1,22 @@
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["divA"] // Add targets for all your divs
connect() {
this.toggleDivs() // Call on connect to set initial state
}
toggleDivs() {
const selectedValue = this.element.querySelector('select').value;
console.log("sv: ")
// Hide all divs first
this.divATarget.classList.add("hidden");
// Show the relevant div based on selection
if (selectedValue === "cig+") {
this.divATarget.classList.remove("hidden");
}
}
}
+2
View File
@@ -2,4 +2,6 @@
class ApplicationRecord < ActiveRecord::Base
primary_abstract_class
establish_connection :dev_tools
end
-5
View File
@@ -1,5 +0,0 @@
class Article < ApplicationRecord
has_many :comments, dependent: :destroy
has_rich_text :content
validates_presence_of :title
end
-4
View File
@@ -1,4 +0,0 @@
class Comment < ApplicationRecord
belongs_to :article
broadcasts_to :article
end
+3
View File
@@ -0,0 +1,3 @@
class IdCardBenefit < ApplicationRecord
belongs_to :id_card_benefits_template
end
+5
View File
@@ -0,0 +1,5 @@
class IdCardBenefitsTemplate < ApplicationRecord
has_many :id_card_benefits
end
@@ -0,0 +1,15 @@
module Vhcs
class HlEgglestonCardBenefit < VhcsRecord
self.table_name = 'HLEgglestonCardBenefit'
alias_attribute :id, :Id
alias_attribute :plan_id, :PlanId
alias_attribute :benefit_desc, :BenefitDesc
alias_attribute :benefit, :Benefit
alias_attribute :sequence, :Sequence
alias_attribute :plan_key, :PlanKey
end
end
+14
View File
@@ -0,0 +1,14 @@
module VHCS
class HlPlanCode < VhcsRecord
self.table_name = 'HlPlanCode'
alias_attribute :id, :ID
alias_attribute :group_number, :GroupNumber
alias_attribute :medical_number, :MedicalNumber
alias_attribute :dental_number, :DentalNumber
alias_attribute :plan_key, :PlanKey
alias_attribute :effect_date, :EffectDate
end
end
+15
View File
@@ -0,0 +1,15 @@
module Vhcs
class HLRXCrosRef < VhcsRecord
self.table_name = 'HLRXCrosRef'
alias_attribute :group_no, :GroupNo
alias_attribute :rx_group_id, :RXGroupID
alias_attribute :help_desk, :HelpDesk
alias_attribute :customer_service, :CustomerService
alias_attribute :web_url, :WebUrl
alias_attribute :pl_plan_key, :PLPlanKey
end
end
+5
View File
@@ -0,0 +1,5 @@
class VhcsRecord < ActiveRecord::Base
self.abstract_class = true
# establish_connection :vhcs
connects_to database: { writing: :vhcs, reading: :vhcs }
end
+23
View File
@@ -0,0 +1,23 @@
class ArrayOfItemsType < ActiveModel::Type::Value
# The `cast` method is used to convert an incoming value into the desired type.
def cast(value)
return unless value.present?
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)
value
end
end
ActiveModel::Type.register(:array_of_items, ArrayOfItemsType)
+56
View File
@@ -0,0 +1,56 @@
<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">General Information</h3>
<%= form_with model: @form, url: employer_setup_index_path, local: true do |f| %>
<div class="flex flex-col my-8 space-y-6">
<div class="flex space-x-10">
<div class="w-1/5">
<%= f.text_field :name, label: { text: "Employer Name" }, class: "w-full" %>
</div>
<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">
<%= f.text_field :pl_plan_key, label: { text: "Pl Plan Key" }, class: "w-full" %>
</div>
<div class="w-1/5">
<%= f.text_field :effect_date, label: { text: "Effective Date" }, class: "w-full" %>
</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">
Choose Employer Logo File
</label>
<span id="file_name_display" class="ml-2 text-bluemana font-semibold">No file chosen</span>
<%= f.file_field :employer_logo, class: "hidden", id: "file_upload_input" %>
</div>
<div class="pt-8">
<%= f.submit "Continue to Plans" %>
</div>
</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>
@@ -0,0 +1,41 @@
<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>
@@ -0,0 +1,38 @@
<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>
+47
View File
@@ -0,0 +1,47 @@
<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">Medical Plans</h3>
<div class="flex flex-col pl-6">
<%= form_with model: @form, url: employer_setup_index_path, local: true do |f| %>
<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>
<%= bd_fields.text_field "#{bene.sequence}", label: { text: "Benefit Description #{bene.sequence}" }, value: "#{bene.benefit_desc}" %>
</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">
<%= "Plan #{i + 1}" %>
</div>
<%= f.fields_for :plans do |plan_fields| %>
<div class="pl-1 w-full">
<%= plan_fields.text_field :plan_id, label: { text: "Plan Id" }, class: "w-full" %>
</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>
<% @id_card_template_benefits.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" %>
</div>
</div>
<% end %>
<% end %>
</div>
<% end %>
</div>
<div class="py-10">
<%= f.submit "Continue to Provider Network" %>
</div>
<% end %>
</div>
</div>
@@ -0,0 +1,9 @@
<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">Summary</h3>
<%= form_with model: @form, url: employer_setup_index_path, local: true do |f| %>
<div class="py-10">
<%= f.submit "Submit" %>
</div>
<% end %>
</div>
+5 -3
View File
@@ -5,13 +5,15 @@
<meta name="viewport" content="width=device-width,initial-scale=1">
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= stylesheet_link_tag "tailwind", "data-turbo-track": "reload" %>
<%= stylesheet_link_tag "application", "data-turbo-track": "reload" %>
<%= javascript_importmap_tags %>
<link rel="stylesheet" href="https://cdn.simplecss.org/simple.min.css">
</head>
<body>
<%= yield %>
<body class="w-full flex bg-deepcove">
<main class="w-11/12 mt-28 px-5 flex">
<%= yield %>
</main>
</body>
</html>