Compare commits

..

13 Commits

Author SHA1 Message Date
Jason Jordan 1d9025276d before adding users 2026-04-20 12:12:52 -04:00
Jason Jordan 7ab1143db8 automation and view updates 2026-04-17 15:35:10 -04:00
Jason Jordan 247a075c9c Major features finished 2026-04-15 08:12:47 -04:00
Jason Jordan 9f306d3150 jasper print speed refactor working 2026-03-27 08:04:37 -04:00
Jason Jordan a43c8bf6b5 Before adding workers 2026-03-20 10:46:53 -04:00
Jason Jordan 3300819ed5 Before a few renames 2026-03-19 00:42:27 -04:00
Jason Jordan 011ee91707 working on data printer 2026-03-16 12:09:45 -04:00
Jason Jordan 8c885b3e76 DB restructure, print page 2026-03-13 08:47:13 -04:00
Jason Jordan 6a068243f4 Employer table broken up and new idcard module setup 2026-03-06 10:56:20 -05:00
Jason Jordan 8ecabf60ff self merge conflicts are fun 2026-03-05 14:40:53 -05:00
Jason Jordan b5a1517330 Halfway through table redesign, saving to revert to working version 2026-03-05 11:30:24 -05:00
Jason Jordan ea07afb751 gitignore update 2026-03-03 22:55:58 -05:00
Jason Jordan 942d60c3e0 stable, before a refactor 2026-03-03 22:53:21 -05:00
279 changed files with 133364 additions and 1622 deletions
+4 -1
View File
@@ -74,6 +74,9 @@ yarn-debug.log*
.DS_Store
/app/assets/builds/*
/app/assets/svg/*
!/app/assets/builds/.keep
/mssql-data
/mssql-data
/logo_files
/employer_word_docs
+1 -1
View File
@@ -7,7 +7,7 @@ inherit_gem:
rubocop-rails-omakase: rubocop.yml
AllCops:
TargetRubyVersion: 3.3.9
TargetRubyVersion: 3.4.8
TargetRailsVersion: 7.2.2
DisabledByDefault: true
Exclude:
+1 -1
View File
@@ -1 +1 @@
3.3.9
3.4.8
+8 -3
View File
@@ -3,7 +3,7 @@
source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby "3.3.9"
ruby "3.4.8"
# Bundle edge Rails instead:
# gem "rails", github: "rails/rails", branch: "7-2-stable"
@@ -83,8 +83,13 @@ gem 'devise'
gem 'pundit'
gem "tailwindcss-rails"
gem 'docx'
gem 'rubyzip'
gem 'httparty'
gem 'combine_pdf'
gem 'pdf-reader'
gem 'rails_icons'
gem 'fastimage'
gem 'fastimage'
gem 'rubyzip', require: 'zip'
gem "solid_queue"
gem 'image_processing'
gem 'whenever', require: false
gem 'amatch'
+127 -104
View File
@@ -1,6 +1,7 @@
GEM
remote: https://rubygems.org/
specs:
Ascii85 (2.0.1)
actioncable (7.2.3)
actionpack (= 7.2.3)
activesupport (= 7.2.3)
@@ -56,7 +57,7 @@ GEM
activemodel (= 7.2.3)
activesupport (= 7.2.3)
timeout (>= 0.4.0)
activerecord-sqlserver-adapter (7.2.8)
activerecord-sqlserver-adapter (7.2.9)
activerecord (~> 7.2.0)
tiny_tds
activestorage (7.2.3)
@@ -77,21 +78,25 @@ GEM
minitest (>= 5.1)
securerandom (>= 0.3)
tzinfo (~> 2.0, >= 2.0.5)
addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0)
addressable (2.8.9)
public_suffix (>= 2.0.2, < 8.0)
afm (1.0.0)
amatch (0.6.0)
mize
tins (~> 1)
ast (2.4.3)
base64 (0.3.0)
bcrypt (3.1.20)
bcrypt (3.1.22)
benchmark (0.5.0)
bigdecimal (3.3.1)
bigdecimal (4.0.1)
bindex (0.8.1)
bootsnap (1.18.6)
bootsnap (1.23.0)
msgpack (~> 1.2)
brakeman (7.1.1)
brakeman (8.0.4)
racc
builder (3.3.0)
bundler-audit (0.9.2)
bundler (>= 1.2.0, < 3)
bundler-audit (0.9.3)
bundler (>= 1.2.0)
thor (~> 1.0)
capybara (3.40.0)
addressable
@@ -102,20 +107,21 @@ GEM
rack-test (>= 0.6.3)
regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2)
cgi (0.5.0)
cgi (0.5.1)
chronic (0.10.2)
coderay (1.1.3)
combine_pdf (1.0.31)
matrix
ruby-rc4 (>= 0.1.5)
concurrent-ruby (1.3.5)
connection_pool (2.5.4)
concurrent-ruby (1.3.6)
connection_pool (3.0.2)
crass (1.0.6)
csv (3.3.5)
date (3.5.0)
devise (4.9.4)
date (3.5.1)
devise (5.0.3)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 4.1.0)
railties (>= 7.0)
responders
warden (~> 1.2.3)
diff-lcs (1.6.2)
@@ -123,34 +129,47 @@ GEM
nokogiri (~> 1.13, >= 1.13.0)
rubyzip (>= 2.0, < 4)
drb (2.2.3)
erb (5.1.3)
erb (6.0.2)
erubi (1.13.1)
fastimage (2.4.0)
et-orbi (1.4.0)
tzinfo
fastimage (2.4.1)
ffi (1.17.4-x86_64-linux-gnu)
fugit (1.12.1)
et-orbi (~> 1.4)
raabro (~> 1.4)
globalid (1.3.0)
activesupport (>= 6.1)
httparty (0.23.2)
hashery (2.1.2)
httparty (0.24.2)
csv
mini_mime (>= 1.0.0)
multi_xml (>= 0.5.2)
i18n (1.14.7)
i18n (1.14.8)
concurrent-ruby (~> 1.0)
importmap-rails (2.2.2)
icons (0.8.1)
nokogiri (~> 1.16, >= 1.16.4)
image_processing (1.14.0)
mini_magick (>= 4.9.5, < 6)
ruby-vips (>= 2.0.17, < 3)
importmap-rails (2.2.3)
actionpack (>= 6.0.0)
activesupport (>= 6.0.0)
railties (>= 6.0.0)
io-console (0.8.1)
irb (1.15.3)
io-console (0.8.2)
irb (1.17.0)
pp (>= 0.6.0)
prism (>= 1.3.0)
rdoc (>= 4.0.0)
reline (>= 0.4.2)
jbuilder (2.14.1)
actionview (>= 7.0.0)
activesupport (>= 7.0.0)
json (2.15.2)
json (2.19.2)
language_server-protocol (3.17.0.5)
lint_roller (1.1.0)
logger (1.7.0)
loofah (2.24.1)
loofah (2.25.1)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
mail (2.9.0)
@@ -162,12 +181,17 @@ GEM
marcel (1.1.0)
matrix (0.4.3)
method_source (1.1.0)
mini_magick (5.3.1)
logger
mini_mime (1.1.5)
minitest (5.26.0)
minitest (6.0.2)
drb (~> 2.0)
prism (~> 1.5)
mize (0.6.1)
msgpack (1.8.0)
multi_xml (0.7.2)
bigdecimal (~> 3.1)
net-imap (0.5.12)
multi_xml (0.8.1)
bigdecimal (>= 3.1, < 5)
net-imap (0.6.3)
date
net-protocol
net-pop (0.1.2)
@@ -177,46 +201,40 @@ GEM
net-smtp (0.5.1)
net-protocol
nio4r (2.7.5)
nokogiri (1.18.10-aarch64-linux-gnu)
racc (~> 1.4)
nokogiri (1.18.10-aarch64-linux-musl)
racc (~> 1.4)
nokogiri (1.18.10-arm-linux-gnu)
racc (~> 1.4)
nokogiri (1.18.10-arm-linux-musl)
racc (~> 1.4)
nokogiri (1.18.10-arm64-darwin)
racc (~> 1.4)
nokogiri (1.18.10-x86_64-darwin)
racc (~> 1.4)
nokogiri (1.18.10-x86_64-linux-gnu)
racc (~> 1.4)
nokogiri (1.18.10-x86_64-linux-musl)
nokogiri (1.19.2-x86_64-linux-gnu)
racc (~> 1.4)
orm_adapter (0.5.0)
parallel (1.27.0)
parser (3.3.10.0)
parser (3.3.10.2)
ast (~> 2.4.1)
racc
pdf-reader (2.15.1)
Ascii85 (>= 1.0, < 3.0, != 2.0.0)
afm (>= 0.2.1, < 2)
hashery (~> 2.0)
ruby-rc4
ttfunk
pp (0.6.3)
prettyprint
prettyprint (0.2.0)
prism (1.6.0)
pry (0.15.2)
prism (1.9.0)
pry (0.16.0)
coderay (~> 1.1)
method_source (~> 1.0)
reline (>= 0.6.0)
pry-rails (0.3.11)
pry (>= 0.13.0)
psych (5.2.6)
psych (5.3.1)
date
stringio
public_suffix (6.0.2)
public_suffix (7.0.5)
puma (6.6.1)
nio4r (~> 2.0)
pundit (2.5.2)
activesupport (>= 3.0.0)
raabro (1.4.0)
racc (1.8.1)
rack (3.2.4)
rack (3.2.5)
rack-mini-profiler (4.0.1)
rack (>= 1.2.0)
rack-session (2.1.1)
@@ -224,7 +242,7 @@ GEM
rack (>= 3.0.0)
rack-test (2.2.0)
rack (>= 1.3)
rackup (2.2.1)
rackup (2.3.1)
rack (>= 3)
rails (7.2.3)
actioncable (= 7.2.3)
@@ -244,11 +262,11 @@ GEM
activesupport (>= 5.0.0)
minitest
nokogiri (>= 1.6)
rails-html-sanitizer (1.6.2)
loofah (~> 2.21)
rails-html-sanitizer (1.7.0)
loofah (~> 2.25)
nokogiri (>= 1.15.7, != 1.16.7, != 1.16.6, != 1.16.5, != 1.16.4, != 1.16.3, != 1.16.2, != 1.16.1, != 1.16.0.rc1, != 1.16.0)
rails_icons (1.5.1)
nokogiri (~> 1.16, >= 1.16.4)
rails_icons (1.7.1)
icons (~> 0.8.1)
rails (>= 7.0)
railties (7.2.3)
actionpack (= 7.2.3)
@@ -262,12 +280,14 @@ GEM
zeitwerk (~> 2.6)
rainbow (3.1.1)
rake (13.3.1)
rdoc (6.15.1)
rdoc (7.2.0)
erb
psych (>= 4.0.0)
tsort
readline (0.0.4)
reline
regexp_parser (2.11.3)
reline (0.6.2)
reline (0.6.3)
io-console (~> 0.5)
responders (3.2.0)
actionpack (>= 7.0)
@@ -278,19 +298,19 @@ GEM
rspec-expectations (3.13.5)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0)
rspec-mocks (3.13.7)
rspec-mocks (3.13.8)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0)
rspec-rails (8.0.2)
rspec-rails (8.0.4)
actionpack (>= 7.2)
activesupport (>= 7.2)
railties (>= 7.2)
rspec-core (~> 3.13)
rspec-expectations (~> 3.13)
rspec-mocks (~> 3.13)
rspec-support (~> 3.13)
rspec-support (3.13.6)
rubocop (1.81.7)
rspec-core (>= 3.13.0, < 5.0.0)
rspec-expectations (>= 3.13.0, < 5.0.0)
rspec-mocks (>= 3.13.0, < 5.0.0)
rspec-support (>= 3.13.0, < 5.0.0)
rspec-support (3.13.7)
rubocop (1.86.0)
json (~> 2.3)
language_server-protocol (~> 3.17.0.2)
lint_roller (~> 1.1.0)
@@ -298,17 +318,17 @@ GEM
parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 2.9.3, < 3.0)
rubocop-ast (>= 1.47.1, < 2.0)
rubocop-ast (>= 1.49.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 4.0)
rubocop-ast (1.47.1)
rubocop-ast (1.49.1)
parser (>= 3.3.7.2)
prism (~> 1.4)
prism (~> 1.7)
rubocop-performance (1.26.1)
lint_roller (~> 1.1)
rubocop (>= 1.75.0, < 2.0)
rubocop-ast (>= 1.47.1, < 2.0)
rubocop-rails (2.33.4)
rubocop-rails (2.34.3)
activesupport (>= 4.2.0)
lint_roller (~> 1.1)
rack (>= 1.1)
@@ -318,19 +338,29 @@ GEM
rubocop (>= 1.72)
rubocop-performance (>= 1.24)
rubocop-rails (>= 2.30)
rubocop-rspec (3.7.0)
rubocop-rspec (3.9.0)
lint_roller (~> 1.1)
rubocop (~> 1.72, >= 1.72.1)
rubocop (~> 1.81)
ruby-progressbar (1.13.0)
ruby-rc4 (0.1.5)
ruby-vips (2.3.0)
ffi (~> 1.12)
logger
rubyzip (3.2.2)
securerandom (0.4.1)
selenium-webdriver (4.38.0)
selenium-webdriver (4.41.0)
base64 (~> 0.2)
logger (~> 1.4)
rexml (~> 3.2, >= 3.2.5)
rubyzip (>= 1.2.2, < 4.0)
websocket (~> 1.0)
solid_queue (1.4.0)
activejob (>= 7.1)
activerecord (>= 7.1)
concurrent-ruby (>= 1.3.1)
fugit (~> 1.11)
railties (>= 7.1)
thor (>= 1.3.1)
sprockets (4.2.2)
concurrent-ruby (~> 1.0)
logger
@@ -341,38 +371,31 @@ GEM
sprockets (>= 3.0.0)
stimulus-rails (1.3.4)
railties (>= 6.0.0)
stringio (3.1.7)
stringio (3.2.0)
sync (0.5.0)
tailwindcss-rails (4.4.0)
railties (>= 7.0.0)
tailwindcss-ruby (~> 4.0)
tailwindcss-ruby (4.1.16)
tailwindcss-ruby (4.1.16-aarch64-linux-gnu)
tailwindcss-ruby (4.1.16-aarch64-linux-musl)
tailwindcss-ruby (4.1.16-arm64-darwin)
tailwindcss-ruby (4.1.16-x86_64-darwin)
tailwindcss-ruby (4.1.16-x86_64-linux-gnu)
tailwindcss-ruby (4.1.16-x86_64-linux-musl)
thor (1.4.0)
timeout (0.4.4)
tiny_tds (3.3.0)
bigdecimal (~> 3)
tiny_tds (3.3.0-aarch64-linux-gnu)
bigdecimal (~> 3)
tiny_tds (3.3.0-aarch64-linux-musl)
bigdecimal (~> 3)
tiny_tds (3.3.0-x86_64-linux-gnu)
bigdecimal (~> 3)
tiny_tds (3.3.0-x86_64-linux-musl)
bigdecimal (~> 3)
tailwindcss-ruby (4.2.1-x86_64-linux-gnu)
thor (1.5.0)
timeout (0.6.1)
tins (1.52.0)
bigdecimal
mize (~> 0.6)
readline
sync
tiny_tds (3.4.0-x86_64-linux-gnu)
bigdecimal (>= 2.0.0)
tsort (0.2.0)
turbo-rails (2.0.20)
ttfunk (1.7.0)
turbo-rails (2.0.23)
actionpack (>= 7.1.0)
railties (>= 7.1.0)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
unicode-display_width (3.2.0)
unicode-emoji (~> 4.1)
unicode-emoji (4.1.0)
unicode-emoji (4.2.0)
useragent (0.16.11)
warden (1.2.9)
rack (>= 2.0.9)
@@ -386,22 +409,18 @@ GEM
base64
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
whenever (1.1.2)
chronic (>= 0.6.3)
xpath (3.2.0)
nokogiri (~> 1.8)
zeitwerk (2.7.3)
zeitwerk (2.7.5)
PLATFORMS
aarch64-linux-gnu
aarch64-linux-musl
arm-linux-gnu
arm-linux-musl
arm64-darwin
x86_64-darwin
x86_64-linux-gnu
x86_64-linux-musl
x86_64-linux
DEPENDENCIES
activerecord-sqlserver-adapter
amatch
bootsnap
brakeman
bundler-audit
@@ -411,8 +430,10 @@ DEPENDENCIES
docx
fastimage
httparty
image_processing
importmap-rails
jbuilder
pdf-reader
pry-rails
puma (~> 6.5)
pundit
@@ -425,6 +446,7 @@ DEPENDENCIES
rubocop-rspec
rubyzip
selenium-webdriver
solid_queue
sprockets-rails
stimulus-rails
tailwindcss-rails
@@ -432,9 +454,10 @@ DEPENDENCIES
turbo-rails
tzinfo-data
web-console
whenever
RUBY VERSION
ruby 3.3.9p170
ruby 3.4.8p72
BUNDLED WITH
2.5.22
2.6.9
+6
View File
@@ -19,6 +19,8 @@
--color-cobalt: #0047AB;
/* cobalt blue */
--color-cobalt-tinted: #003B8F;
/* cobalt blue */
--color-cobalt-vivid: #005DE0;
/* platinum */
--color-platinum: #E0E0E0;
/* copper */
@@ -33,6 +35,10 @@
--color-verdigris: #588288;
/* oxidized copper/bronze green-blue */
--color-verdigris-tinted: #496A6F;
/* oxidized copper/bronze green-blue */
--color-verdigris-vivid: #618D94;
/* alert red */
--color-brightlava: #f80800;
/* alert green */
--color-limegreen: #32CD32;
}
+1 -1
View File
@@ -18,7 +18,7 @@ class EmployerSetupController < ApplicationController
word_doc = params[:employer_setup_process][:import_from_word]
@plan_templates = IdCardBenefitsTemplate.where.not(title: "BLANK")
if word_doc.present? && word_doc.is_a?(ActionDispatch::Http::UploadedFile)
@employer_setup = BenefitsWordDocProcessor.new(word_doc.tempfile).call
@employer_setup = WordDocProcessor.new(word_doc.tempfile).call
render :edit
else
@employer_setup = EmployerSetupProcess.new
+43 -17
View File
@@ -1,6 +1,10 @@
class EmployersController < ApplicationController
# View Methods
def index
@employers = Employer.all
@uninitialized = Employer.in_automation_initilization
@with_active_id_card_setup = Employer.with_active_id_card_setup
@deactivated = Employer.deactivated
end
def show
@@ -9,22 +13,20 @@ class EmployersController < ApplicationController
def new
@employer = Employer.new
@employer.build_plan_with_default_benefits
@plan_templates = IdCardBenefitsTemplate.where.not(title: "BLANK")
render :new
end
def import
word_doc = params[:employer][:import_from_word]
@plan_templates = IdCardBenefitsTemplate.where.not(title: "BLANK")
if word_doc.present? && word_doc.is_a?(ActionDispatch::Http::UploadedFile)
@employer = BenefitsWordDocProcessor.new(word_doc.tempfile).call
else
@employer = Employer.new
@employer.build_plan_with_default_benefits
end
render :new
end
# def import_old
# word_doc = params[:employer][:import_from_word]
# @plan_templates = IdCardBenefitsTemplate.where.not(title: "BLANK")
# if word_doc.present? && word_doc.is_a?(ActionDispatch::Http::UploadedFile)
# @employer = WordDocProcessor.new(word_doc.tempfile).call
# else
# @employer = Employer.new
# @employer.build_plan_with_default_benefits
# end
# render :new
# end
def create
employer_params = Employer.permitted_params(params)
@@ -36,16 +38,13 @@ class EmployersController < ApplicationController
# update_logos_with_employer_setup_information()
redirect_to employer_path(@employer.slug), notice: 'Employer Saved'
else
@plan_templates = IdCardBenefitsTemplate.where.not(title: "BLANK")
render :new
end
end
def edit
@employer = Employer.find_by(slug: params[:id])
@plan_templates = IdCardBenefitsTemplate.where.not(title: "BLANK")
render :edit
# @resource = Resource.find(params[:id])
end
def update
@@ -69,6 +68,33 @@ class EmployersController < ApplicationController
# redirect_to resources_url, notice: 'Resource was successfully destroyed.'
end
# API Methods
def refresh_employer_information
@employer = Employer.find(params[:id])
@employer.sync_with_vhcs
redirect_to employer_path(@employer.slug)
end
def refresh_employer_members_information
@employer = Employer.find(params[:id])
@employer.sync_members_with_vhcs
redirect_to employer_path(@employer.slug)
end
def import
word_doc = params[:employer][:import_from_word]
if word_doc.present? && word_doc.is_a?(ActionDispatch::Http::UploadedFile)
@employer = BenefitsWordDocService::WordDocProcessor.new(word_doc.tempfile).call
@employer.save
redirect_to employer_path(@employer.slug), notice: 'Employer Imported'
else
@employer = Employer.new
render :new
end
end
private
# def process_logos(employer_setup_process_params)
@@ -0,0 +1,61 @@
module IdCard
class EmployerLogosController < ApplicationController
# View Methods
def index
end
def show
end
def new
end
def create
file = logo_params["logo_file"]
if file.present? && file.is_a?(ActionDispatch::Http::UploadedFile)
filename = file.original_filename
# binary_data = file.read
binary_data = File.binread(file)
meme_type = Marcel::MimeType.for(file)
employerlogo = IdCard::EmployerLogo.create(
filename: filename,
image_data: binary_data,
content_type: meme_type
)
render json: employerlogo, only: [:id], status: :ok
end
end
def edit
end
def update
end
def destroy
end
# API Methods
def image
logo_file = IdCard::EmployerLogo.find(params[:id])
puts params[:id]
logo_binary = logo_file.image_data
logo_filename = logo_file.filename
send_data logo_binary,
filename: logo_filename,
disposition: 'inline'
end
private
def logo_params
params.require(:id_card_employer_logo).permit(:logo_file)
end
end
end
@@ -0,0 +1,61 @@
module IdCard
class NetworkLogosController < ApplicationController
# View Methods
def index
end
def show
end
def new
end
def create
file = logo_params["logo_file"]
if file.present? && file.is_a?(ActionDispatch::Http::UploadedFile)
filename = file.original_filename
# binary_data = file.read
binary_data = File.binread(file)
meme_type = Marcel::MimeType.for(file)
networklogo = IdCard::NetworkLogo.create(
filename: filename,
image_data: binary_data,
content_type: meme_type
)
render json: networklogo, only: [:id], status: :ok
end
end
def edit
end
def update
end
def destroy
end
# API Methods
def image
logo_file = IdCard::NetworkLogo.find(params[:id])
puts params[:id]
logo_binary = logo_file.image_data
logo_filename = logo_file.filename
send_data logo_binary,
filename: logo_filename,
disposition: 'inline'
end
private
def logo_params
params.require(:id_card_network_logo).permit(:logo_file)
end
end
end
@@ -0,0 +1,40 @@
module IdCard
class PlansController < ApplicationController
# View Methods
def new
end
def create
end
def edit
end
def update
end
def destroy
end
# API Methods
def get_plan_template
@template_plan = IdCard::Plan.includes(:plan_benefits).find_by(id: params[:id], template: true)
render json: @template_plan.as_json(
only: [:title],
include: {
plan_benefits: { except: [:id, :plan_id, :created_at, :updated_at] }
}
)
end
private
end
end
+123
View File
@@ -0,0 +1,123 @@
module IdCard
class PrintController < ApplicationController
# View Methods
def index
@employer_setups = IdCard::Setup.active.to_a
@queue_members = IdCardQueueService::GetQueuedMembers.new().call
add_queued_count_to_employer_setup(@queue_members)
@queued = @employer_setups.select { |setup| setup.queued_card_count > 0 }.sort_by { |setup| setup.print_name }
@not_queued = @employer_setups.select { |setup| setup.queued_card_count == 0 }.sort_by { |setup| setup.print_name }
render :index
end
# API Methods
def print_all_queued
@queue_members = IdCardQueueService::GetQueuedMembers.new().call
cards_pdf = IdCardPrinterService::CardsGenerator.new(@queue_members, "PrintCard").call
send_data cards_pdf.to_pdf,
filename: "all_queued_cards_#{Date.today}.pdf",
type: "application/pdf",
disposition: 'attachment'
end
def print_queued_by_employer
pl_plan_key = params[:id].to_s
@employer = Employer.find_by(pl_plan_key: pl_plan_key)
@queue_members = IdCardQueueService::GetQueuedMembers.new(pl_plan_key).call
cards_pdf = IdCardPrinterService::CardsGenerator.new(@queue_members, "PrintCard").call
send_data cards_pdf.to_pdf,
filename: "#{@employer.name.parameterize(separator: "_")}_queued_cards_#{Date.today}.pdf",
type: "application/pdf",
disposition: 'attachment'
end
def generate_sample
if Integer(params[:id], exception: false).is_a?(Integer)
pl_plan_key = params[:id].to_s
@employer = Employer.find_by(pl_plan_key: pl_plan_key)
else
slug = params[:id]
@employer = Employer.find_by(slug: slug)
end
sample_cards_pdf = IdCardPrinterService::SampleCardsGenerator.new(@employer).call
send_data sample_cards_pdf.to_pdf,
filename: "#{@employer.name.parameterize(separator: "_")}_sample_cards_#{Date.today}.pdf",
type: "application/pdf",
disposition: 'attachment'
end
def generate_print
if Integer(params[:id], exception: false).is_a?(Integer)
pl_plan_key = params[:id].to_s
@employer = Employer.find_by(pl_plan_key: pl_plan_key)
else
slug = params[:id]
@employer = Employer.find_by(slug: slug)
end
cards_pdf = IdCardPrinterService::CardsGenerator.new(@employer.employer_member_keys, "PrintCard").call
send_data cards_pdf.to_pdf,
filename: "#{@employer.name.parameterize(separator: "_")}_print_cards_#{Date.today}.pdf",
type: "application/pdf",
disposition: 'attachment'
end
def generate_mobile_display
if Integer(params[:id], exception: false).is_a?(Integer)
pl_plan_key = params[:id].to_s
@employer = Employer.find_by(pl_plan_key: pl_plan_key)
else
slug = params[:id]
@employer = Employer.find_by(slug: slug)
end
cards_pdf = IdCardPrinterService::EmployerCardsGenerator.new(@employer, "MobileDisplayCard").call
send_data cards_pdf.to_pdf,
filename: "#{@employer.name.parameterize(separator: "_")}_mobile_display_cards_#{Date.today}.pdf",
type: "application/pdf",
disposition: 'attachment'
end
def generate_full_page
if Integer(params[:id], exception: false).is_a?(Integer)
pl_plan_key = params[:id].to_s
@employer = Employer.find_by(pl_plan_key: pl_plan_key)
else
slug = params[:id]
@employer = Employer.find_by(slug: slug)
end
cards_pdf = IdCardPrinterService::CardsGenerator.new(@employer.employer_member_keys, "FullPageCard", true).call
# cards_pdf = IdCardPrinterService::EmployerCardsGenerator.new(@employer, "FullPageCard", true).call
cards_pdf.rewind
send_data cards_pdf.sysread,
filename: "#{@employer.name.parameterize(separator: "_")}_full_page_cards_#{Date.today}.zip",
type: 'application/zip',
disposition: 'attachment'
end
private
def add_queued_count_to_employer_setup(queued_employer_members)
queued_employer_members.each do |queued_employer|
match = @employer_setups.find { |setup| setup.pl_plan_key == queued_employer[:pl_plan_key] }
if match.present?
match.queued_card_count = queued_employer[:member_keys].length
end
end
end
end
end
@@ -0,0 +1,49 @@
module IdCard
class PrintDataController < ApplicationController
def generate_sample
@employer = Employer.find_by(slug: params[:employer_slug])
sample_cards_pdf = IdCardPrinterService::SampleCardsGenerator.new(@employer).call
send_data sample_cards_pdf.to_pdf,
filename: "#{@employer.name.parameterize(separator: "_")}_sample_cards_#{Date.today}.pdf",
type: "application/pdf",
disposition: 'attachment'
end
def generate_print
@employer = Employer.find_by(slug: params[:employer_slug])
cards_pdf = IdCardPrinterService::EmployerCardsGenerator.new(@employer, "PrintCard").call
send_data cards_pdf.to_pdf,
filename: "#{@employer.name.parameterize(separator: "_")}_print_cards_#{Date.today}.pdf",
type: "application/pdf",
disposition: 'attachment'
end
def generate_mobile_display
@employer = Employer.find_by(slug: params[:employer_slug])
cards_pdf = IdCardPrinterService::EmployerCardsGenerator.new(@employer, "MobileDisplayCard").call
send_data cards_pdf.to_pdf,
filename: "#{@employer.name.parameterize(separator: "_")}_mobile_display_cards_#{Date.today}.pdf",
type: "application/pdf",
disposition: 'attachment'
end
def generate_full_page
@employer = Employer.find_by(slug: params[:employer_slug])
cards_pdf = IdCardPrinterService::EmployerCardsGenerator.new(@employer, "FullPageCard", true).call
cards_pdf.rewind
send_data cards_pdf.sysread,
filename: "#{@employer.name.parameterize(separator: "_")}_full_page_cards_#{Date.today}.zip",
type: 'application/zip',
disposition: 'attachment'
end
end
end
@@ -0,0 +1,40 @@
module IdCard
class ProviderSectionsController < ApplicationController
# View Methods
def index
end
def show
end
def new
end
def create
end
def edit
end
def update
end
def destroy
end
# API Methods
def get_section_data
@provider_section = IdCard::ProviderSection.find(params[:id])
render json: @provider_section.as_json
end
private
def logo_params
params.require(:id_card_network_logo).permit(:logo_file)
end
end
end
+306
View File
@@ -0,0 +1,306 @@
module IdCard
class SetupController < ApplicationController
before_action :set_employer_and_setup
# View Methods
# def edit
# @employer = Employer.find_by(slug: params[:employer_id])
# if @employer.id_card_enabled?
# @setup = @employer.id_card_setup
# else
# @setup = @employer.create_id_card_setup
# end
# render :edit
# end
# def update
# setup_params = IdCard::Setup.permitted_params(params)
# @setup = IdCard::Setup.find(params[:id])
# if @setup.update(setup_params)
# puts "sucess"
# redirect_to employer_path(@setup.employer.slug), notice: 'ID Card Setup was successfully updated.'
# else
# puts "fail"
# render :edit, status: :unprocessable_entity
# end
# end
def index
provider_defaults = IdCard::ProviderSection.defaults
@provider_options = provider_defaults.map { |p| ["Default #{p.title}", p.id] }.concat(provider_defaults.map { |p| ["New #{p.title}", "new|#{p.id}"] })
if @setup.provider_section_id.present? && provider_defaults.map(&:id).exclude?(@setup.provider_section_id)
@provider_options.insert(0, ["#{@employer.name} Custom", @setup.provider_section_id])
end
@rx_options = IdCard::RxSection.all
@fairos_rx_id = IdCard::RxSection.find_by(title: "FairosRx").id
render :index
end
def update
if params[:id_card_setup]["provider_section_id"].include?("new|")
new_provider_section_params = IdCard::ProviderSection.permitted_params(params)
new_provider_section = IdCard::ProviderSection.create(new_provider_section_params)
params[:id_card_setup]["provider_section_id"] = new_provider_section.id
end
setup_params = IdCard::Setup.permitted_params(params)
if @setup.update(setup_params)
puts "sucess"
redirect_to employer_path(@employer.slug), notice: 'ID Card Setup was successfully updated.'
else
puts "fail"
render :index, status: :unprocessable_entity
end
end
def plans
@plan_templates = IdCard::Plan.templates
render :plans
end
def update_plans
plans_params = IdCard::Plan.permitted_params(params)
if @setup.update(plans_params)
puts "sucess"
redirect_to employer_path(@setup.employer.slug), notice: 'ID Card Plans successfully updated.'
else
puts "fail"
render :plans, status: :unprocessable_entity
end
end
def field_exceptions
render :field_exceptions
end
def update_field_exceptions
field_exceptions_params = IdCard::FieldException.permitted_params(params)
if @setup.update(field_exceptions_params)
puts "sucess"
redirect_to employer_path(@setup.employer.slug), notice: 'ID Card Exceptions successfully updated.'
else
puts "fail"
render :field_exceptions, status: :unprocessable_entity
end
end
def update_active_status
@setup.active = !@setup.active
if @setup.save
puts "sucess"
redirect_to employer_path(@setup.employer.slug), notice: 'ID Card Active Status successfully updated.'
else
puts "fail"
render :show, status: :unprocessable_entity
end
end
def destroy
# @resource = Resource.find(params[:id])
# @resource.destroy
# redirect_to resources_url, notice: 'Resource was successfully destroyed.'
end
# API Methods
private
def set_employer_and_setup
@employer = Employer.find_by(slug: params[:employer_id])
if @employer.id_card_setup.present?
@setup = @employer.id_card_setup
else
@setup = @employer.create_id_card_setup
end
end
# def process_logos(employer_setup_process_params)
# @uploaded_logos = []
# employer_logo = employer_setup_process_params["employer_logo"]
# if employer_logo.present? && employer_logo.is_a?(ActionDispatch::Http::UploadedFile)
# filename = employer_logo.original_filename
# binary_data = employer_logo.read
# meme_type = Marcel::MimeType.for(employer_logo)
# CardLogoFile.create(
# filename: filename,
# image_data: binary_data,
# content_type: meme_type,
# logo_type: "employer"
# )
# @uploaded_logos.push(filename)
# employer_setup_process_params["employer_logo"] = filename
# end
# network_logos = employer_setup_process_params["alternate_network_logos_attributes"]
# if network_logos.present?
# network_logos.each do |alt|
# network_logo = alt.last["network_logo"]
# if network_logo.present? && network_logo.is_a?(ActionDispatch::Http::UploadedFile)
# filename = network_logo.original_filename
# binary_data = network_logo.read
# meme_type = Marcel::MimeType.for(network_logo)
# CardLogoFile.create(
# filename: filename,
# image_data: binary_data,
# content_type: meme_type,
# logo_type: "network"
# )
# @uploaded_logos.push(filename)
# end
# alt.last["network_logo"] = @uploaded_logos.last
# end
# end
# employer_setup_process_params
# end
# def update_logos_with_employer_setup_information()
# @uploaded_logos.each do |logo|
# logo_file = CardLogoFile.find_by(filename: logo)
# if logo_file.present? && @employer.present?
# logo_file.employer_setup_process = @employer
# logo_file.save
# end
# end
# 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 network_field_exceptions_params
# params.require(:employer_setup_network_field_exceptions_form).permit(
# network_field_exceptions: [:network_logo, field_exceptions: [:type, :value]],
# )
# end
# def form_for_step
# step_name = @top_form.current_step
# form_method = "EmployerSetup#{step_name.camelize}Form".constantize
# # puts "/////\\\\\\||||||"
# # puts session[:employer_setup_data]
# # puts session[:employer_setup_data]['employer_setup_process_id']
# puts form_method
# form_method.new(session[:employer_setup_data]['employer_setup_process_id'])
# end
# def process_step(step_name)
# @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]
# employer_setup_process_id = session[:employer_setup_data]['employer_setup_process_id']
# # puts session[:employer_setup_data]
# puts "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
# puts params
# @form = @form_method.new(employer_setup_process_id, 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].merge!({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
# 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
# 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
# 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_field_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(
# :current_step,
# :name,
# :employer_logo,
# :group_number,
# :pl_plan_key,
# :effect_date,
# :number_of_plans,
# :network,
# :number_of_additional_network_logos,
# network_field_exceptions: [:network_logo, field_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
end
@@ -0,0 +1,57 @@
class IdCardEmployerLogoController < ApplicationController
def index
end
def show
end
def image
logo_file = IdCard::EmployerLogo.find_by(filename: params[:id])
puts params[:id]
if logo_file
logo_binary = logo_file.image_data
logo_filename = logo_file.filename
send_data logo_binary,
filename: logo_filename,
disposition: 'inline'
end
end
def new
end
def create
file = card_logo_file_params["logo_file"]
if file.present? && file.is_a?(ActionDispatch::Http::UploadedFile)
filename = file.original_filename
# binary_data = file.read
binary_data = File.binread(file)
meme_type = Marcel::MimeType.for(file)
CardLogoFile.create(
filename: filename,
image_data: binary_data,
content_type: meme_type,
logo_type: card_logo_file_params["logo_type"]
)
end
end
def edit
end
def update
end
def destroy
end
private
def card_logo_file_params
params.require(:card_logo_file).permit(:logo_file, :logo_type)
end
end
@@ -1,25 +0,0 @@
class SampleIdCardsController < ApplicationController
def generate_sample
@employer = Employer.find_by(slug: params[:employer_slug])
sample_cards_pdf = SampleCardGenerator.new(@employer).call
send_data sample_cards_pdf.to_pdf,
filename: "#{@employer.name.parameterize(separator: "_")}_sample_cards_#{Date.today}.pdf",
type: "application/pdf",
disposition: 'attachment'
end
def generate_print
@employer = Employer.find_by(slug: params[:employer_slug])
sample_cards_pdf = EmployerCardsGenerator.new(@employer).call
send_data sample_cards_pdf.to_pdf,
filename: "#{@employer.name.parameterize(separator: "_")}_print_cards_#{Date.today}.pdf",
type: "application/pdf",
disposition: 'attachment'
end
end
+1 -1
View File
@@ -70,7 +70,7 @@ class TailwindFormBuilder < ActionView::Helpers::FormBuilder
text, label_opts = if label_options.present?
[label_options[:text], label_options.except(:text)]
else
[nil, {}]
[object_method.to_s.titleize, {}]
end
label_classes = label_opts[:class] || "block text-platinum font-bold md:text-right mb-1 md:mb-0 pr-4"
+2
View File
@@ -0,0 +1,2 @@
module CardProvidersHelper
end
+2
View File
@@ -0,0 +1,2 @@
module CardRxesHelper
end
@@ -4,19 +4,23 @@ export default class extends Controller {
static values = {
formColor: { type: Array, default: [] } // Declares 'items' as an Array value
}
static targets = ["template", "container", "networkLogo", "button"]
static targets = ["exceptionTemplate", "exceptionContainer", "exception", "exceptionButton"]
add(event) {
connect(){
console.log(this.formColorValue)
}
addExemption(event) {
event.preventDefault()
event.stopPropagation()
const content = this.#updateTemplateNetwork()
const content = this.#newExemption()
this.buttonTarget.insertAdjacentHTML('beforebegin', content);
this.exceptionButtonTarget.insertAdjacentHTML('beforebegin', content);
// this.containerTarget.insertAdjacentHTML("beforeend", content)
}
remove(event) {
removeExemption(event) {
event.preventDefault();
const wrapper = event.target.closest(".network-item");
if (wrapper.dataset.newRecord === "true") {
@@ -30,22 +34,19 @@ export default class extends Controller {
}
}
#updateTemplateNetwork() {
const nextIndex = this.networkLogoTargets.length
#newExemption() {
const nextIndex = this.exceptionTargets.length
const num_of_colors = this.formColorValue.length
let colorIndex = 0
let newSecondaryColor = "copper"
if (nextIndex != 0) {
colorIndex = nextIndex % num_of_colors
if (nextIndex % 2 == 1) {
newSecondaryColor = "bronze"
}
}
const newColor = this.formColorValue[colorIndex]
return this.templateTarget.innerHTML
return this.exceptionTemplateTarget.innerHTML
.replace(/NEW_RECORD/g, nextIndex)
.replace(/NEXT_COLOR/g, newColor)
.replace(/NEXT_SECONDARY_COLOR/g, newSecondaryColor)
}
}
@@ -0,0 +1,53 @@
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["exceptionItemTemplate", "exceptionItemContainer", "exceptionItem", "exceptionItemButton"]
connect() {
// if (this.exceptionItemTargets.length > 0) {
// const content = this.#newExemptionItem()
// this.exceptionItemButtonTarget.insertAdjacentHTML('beforebegin', content);
// }
}
addExemptionItem(event) {
event.preventDefault()
event.stopPropagation()
const content = this.#newExemptionItem()
this.exceptionItemButtonTarget.insertAdjacentHTML('beforebegin', content);
// this.containerTarget.insertAdjacentHTML("beforeend", content)
}
removeExemptionItem(event) {
console.log("in remove")
event.preventDefault();
const wrapper = event.target.closest(".exception-item");
if (wrapper.dataset.newRecord === "true") {
wrapper.remove();
} else {
wrapper.style.display = "none";
const destroyInput = wrapper.querySelector("input[name*='[_destroy]']");
if (destroyInput) {
destroyInput.value = "1";
}
}
}
#newExemptionItem() {
const nextIndex = this.exceptionItemTargets.length
console.log(nextIndex)
const buttonElement = this.exceptionItemButtonTarget;
// Get the computed style (returns rgb/rgba value)
const bgColor = window.getComputedStyle(buttonElement).backgroundColor;
const newColor = `[${bgColor}]`
return this.exceptionItemTemplateTarget.innerHTML
.replace(/NEW_ITEM_RECORD/g, nextIndex)
.replace(/NEXT_COLOR/g, newColor)
}
}
@@ -33,6 +33,7 @@ export default class extends Controller {
#updateTemplatePlan() {
const nextIndex = this.planTargets.length
console.log(nextIndex)
const num_of_colors = this.formColorValue.length
let colorIndex = 0
let newSecondaryColor = "copper"
@@ -2,7 +2,7 @@ import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
static values = { url: String };
static targets = ["benefit"];
static targets = ["benefit", "title"];
connect() {
}
@@ -14,19 +14,21 @@ export default class extends Controller {
return;
}
const url = `/id_card_benefits_templates/get_template_benefits/${templateId}`
const url = `/id_card/plans/${templateId}/get_plan_template`
const response = await fetch(url);
const templateBenefitsData = await response.json();
const templatePlanData = await response.json();
this.#updateFields(templateBenefitsData)
this.#updateFields(templatePlanData)
}
clearFields() {
}
async #updateFields(templateBenefitsData) {
async #updateFields(templatePlanData) {
const titleElement = this.titleTarget
titleElement.value = templatePlanData.title.match(/^(.*\d)k(?=\d)/i)[0].replace(/(\d)/, ' $1')
const benefitTargetsList = this.benefitTargets
templateBenefitsData.forEach(function(bene) {
templatePlanData.plan_benefits.forEach(function(bene) {
const targetElement = benefitTargetsList.find(
(element) => element.dataset.sequence == bene.sequence
);
@@ -0,0 +1,57 @@
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["dependentField", "providerField", "selectField"]
connect() {
console.log("--- in toggle connect --- ")
const selector = this.selectFieldTarget;
if (selector.value) {
const selectedValue = selector.value
this.dependentFieldTargets.forEach((field) => {
if (field.value) {
if (selectedValue == "network_logo") {
field.parentElement.parentElement.parentElement.classList.remove("hidden");
} else {
field.parentElement.classList.remove("hidden");
}
}
})
}
}
toggleFields() {
console.log("--- in toggle --- ")
const selector = this.selectFieldTarget;
if (selector.value) {
const selectedValue = selector.value
this.field_match = false;
this.dependentFieldTargets.forEach((field) => {
// console.log("- ", selectedValue)
// console.log("-- ", this.field_match)
// Check a data attribute on the field to see if it matches the selected value
if (field.dataset.parentValue === selectedValue) {
if (selectedValue == "network_logo") {
field.parentElement.parentElement.parentElement.classList.remove("hidden");
} else {
field.parentElement.classList.remove("hidden");
}
this.field_match = true;
} else {
if (field.dataset.parentValue == "network_logo") {
field.parentElement.parentElement.parentElement.classList.add("hidden");
} else {
field.parentElement.classList.add("hidden");
}
}
});
if (!this.field_match) {
console.log("--- ", this.field_match)
const defaultOption = this.dependentFieldTargets.find(target => {
return target.dataset.parentValue === 'default';
});
defaultOption.parentElement.classList.remove("hidden");
}
}
}
}
@@ -0,0 +1,112 @@
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["dependentField", "providerField", "selectField"]
connect() {
if (this.selectFieldTarget.value) {
this.toggleNewFieldSection();
}
}
async initNewFieldSection() {
console.log("--- in init async --- ")
const selector = this.selectFieldTarget
console.log(selector.textContent)
console.log(selector.value)
if (selector && selector.value && !selector.textContent.includes("Default")) {
const sectionId = selector.value
const response = await fetch(`/id_card/provider_sections/${sectionId}/get_section_data`);
const templateSectionData = await response.json();
this.#updateFields(templateSectionData)
this.dependentFieldTarget.classList.remove("hidden");
}
}
async toggleNewFieldSection() {
console.log("--- in new field toggle --- ")
const selector = this.selectFieldTarget
const selectedOption = selector.options[selector.selectedIndex]
const selectedValue = selectedOption.value
const selectedLabel = selectedOption.textContent
if (selectedValue && selectedLabel.includes("Default")) {
this.dependentFieldTarget.classList.add("hidden");
} else if (selectedValue) {
let sectionId = selectedValue
if (selectedValue.includes("new")) {
sectionId = selectedValue.split('|')[1]
}
const response = await fetch(`/id_card/provider_sections/${sectionId}/get_section_data`);
const sectionData = await response.json();
this.#updateFields(sectionData)
this.dependentFieldTarget.classList.remove("hidden");
}
}
async #updateFields(templateSectionData) {
const providerFieldTargetsList = this.providerFieldTargets
console.log(templateSectionData)
providerFieldTargetsList.forEach(function(formField) {
const dbField = formField.id.replace('id_card_setup_provider_section_', '')
const dbValue = templateSectionData[dbField]
formField.value = dbValue;
})
// templateSectionData.forEach(function(data) {
// const targetElement = providerFieldTargetsList.find(
// (element) => element.dataset.sequence == data.sequence
// );
// if (targetElement) {
// targetElement.value = data.benefit;
// } else {
// console.error(`Target not found for sequence: ${data.sequence}`);
// }
// });
}
toggleFields() {
console.log("--- in toggle --- ")
const selector = this.element.querySelector('[data-action*="change->general-form#toggleFields"]');
if (selector) {
const selectedValue = selector.value
this.field_match = false;
this.dependentFieldTargets.forEach((field) => {
// Check a data attribute on the field to see if it matches the selected value
if (field.dataset.parentValue === selectedValue) {
if (selectedValue == "network_logo") {
field.parentElement.parentElement.classList.remove("hidden");
} else {
field.parentElement.classList.remove("hidden");
}
this.field_match = true;
console.log("- ", selectedValue)
console.log("-- ", this.field_match)
} else {
if (field.dataset.parentValue == "network_logo") {
field.parentElement.parentElement.classList.add("hidden");
} else {
field.parentElement.classList.add("hidden");
}
}
});
if (!this.field_match) {
console.log("--- ", this.field_match)
const defaultOption = this.dependentFieldTargets.find(target => {
return target.dataset.parentValue === 'default';
});
defaultOption.parentElement.classList.remove("hidden");
}
}
}
}
+16 -16
View File
@@ -1,16 +1,16 @@
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = [ "name", "output" ]
connect() {
// this.element.textContent = "Hello World!"
console.log('Hello World hello_controller.js');
}
greet() {
console.log('greet');
this.outputTarget.textContent =
`Hello, ${this.nameTarget.value}!`
}
}
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = [ "name", "output" ]
connect() {
// this.element.textContent = "Hello World!"
console.log('Hello World hello_controller.js');
}
greet() {
console.log('greet');
this.outputTarget.textContent =
`Hello, ${this.nameTarget.value}!`
}
}
@@ -0,0 +1,16 @@
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = [ "selector", "link" ]
static values = { urlTemplate: String } // Pass template like "/users/:id/edit"
update() {
console.log("## ## %%")
const selectedId = this.selectorTarget.value
// Replace placeholder with selected ID
const newUrl = this.urlTemplateValue.replace(":id", selectedId)
// Update the link href
this.linkTarget.href = newUrl
}
}
@@ -1,66 +1,101 @@
import { Controller } from "@hotwired/stimulus";
export default class extends Controller {
static targets = ["preview", "previewContainer", "logoSelect", "logofield", "initialLogoFile"];
static values = {
logoType: String,
employerName: String
}
static targets = ["preview", "previewContainer", "logoSelect", "logoIdField", "logoNameField", "initialLogoFile"];
async connect() {
console.log(this.logofieldTarget.value)
if (this.logofieldTarget.value.includes("Logo.")) {
const response = await fetch(`/card_logo_files/${this.logofieldTarget.value}/image`); // Fetch the binary data
console.log('in connect');
this.setPreviewImage()
// Remember to revoke the URL when the controller is disconnected if necessary
// this.disconnect = () => URL.revokeObjectURL(objectUrl);
}
async setPreviewImage() {
const initValue = this.logoIdFieldTarget.value
console.log(initValue)
console.log(this.logoTypeValue)
if (initValue) {
const response = await fetch(`/id_card/${this.logoTypeValue}_logos/${initValue}/image`); // Fetch the binary data
const logoType = this.logoTypeValue
if (logoType == "employer") {
const contentDisposition = response.headers.get('Content-Disposition');
const filename = contentDisposition.match(/filename="?([^"]+)"?/)[1];
this.logoNameFieldTarget.value = filename;
}
const blob = await response.blob();
const objectUrl = URL.createObjectURL(blob);
this.previewTarget.src = objectUrl;
this.previewContainerTarget.classList.remove("hidden");
} else {
this.previewContainerTarget.classList.add("hidden");
}
// Remember to revoke the URL when the controller is disconnected if necessary
// this.disconnect = () => URL.revokeObjectURL(objectUrl);
}
setSelectPreview(event) {
this.setPreviewImage()
}
uploadLogo(event) {
console.log('in uploadLogo');
event.preventDefault()
const file = event.target.files[0];
if (!file) return;
let logoFile = event.target.files[0];
if (!logoFile) return;
const logoType = event.params.type
const logoType = this.logoTypeValue
let newFileName = file.name
let newFileName = logoFile.name
if (logoType == "network") {
console.log("n " + newFileName);
newFileName = this.determineNetworkFilename(file)
this.addOptionToSelect(newFileName)
newFileName = this.determineNetworkFilename(logoFile)
} else if (logoType == "employer") {
newFileName = this.determineEmployerFilename(file)
this.logofieldTarget.value = newFileName;
newFileName = this.determineEmployerFilename(logoFile)
}
logoFile = new File([logoFile], newFileName)
this.uploadLogoToServer(logoFile)
.then((result) => {
console.log(result);
const logoId = result.id
this.previewFile(logoFile);
if (logoType == "network") {
this.addOptionToSelect(newFileName, logoId)
} else {
this.logoNameFieldTarget.value = newFileName;
}
this.logoIdFieldTarget.value = logoId;
this.previewFile(file);
// this.uploadLogoToServer(file);
})
.catch((error) => {
// Handle any errors that occurred
console.error(error);
});
}
previewFile(file) {
previewFile(logoFile) {
console.log('in previewFile');
const reader = new FileReader();
reader.onload = (e) => {
this.previewTarget.src = e.target.result;
this.previewContainerTarget.classList.remove("hidden");
};
reader.readAsDataURL(file);
reader.readAsDataURL(logoFile);
}
async uploadLogoToServer(file) {
async uploadLogoToServer(logoFile) {
console.log('in uploadLogoToServer');
const formData = new FormData();
formData.append("card_logo_file[logo_file]", file);
formData.append("card_logo_file[logo_type]", "employer");
formData.append(`id_card_${this.logoTypeValue}_logo[logo_file]`, logoFile);
const csrfToken = document.querySelector("meta[name='csrf-token']").content;
try {
const response = await fetch("/card_logo_files/", {
const response = await fetch(`/id_card/${this.logoTypeValue}_logos/`, {
method: "POST",
headers: {
"X-CSRF-Token": csrfToken
@@ -70,39 +105,41 @@ export default class extends Controller {
if (response.ok) {
console.log('Upload successful!')
const data = await response.json();
return data;
} else {
console.error("Failed to track event.");
throw new Error(`HTTP error! status: ${response.status}`);
}
} catch (error) {
console.error("Network error:", error);
throw new Error("Network error:", error);
}
}
addOptionToSelect(name) {
addOptionToSelect(name, id) {
const blankOptionIndex = 0;
const newOption = new Option(name, name, true, true)
const newOption = new Option(name, id, true, true)
if (this.logoSelectTarget.options.length > blankOptionIndex + 1) {
this.logoSelectTarget.insertBefore(newOption, this.logoSelectTarget.options[blankOptionIndex + 1]);
if (this.logoIdFieldTarget.options.length > blankOptionIndex + 1) {
this.logoIdFieldTarget.insertBefore(newOption, this.logoIdFieldTarget.options[blankOptionIndex + 1]);
} else {
this.logoSelectTarget.appendChild(newOption);
this.logoIdFieldTarget.appendChild(newOption);
}
this.logoSelectTarget.value = name;
}
determineNetworkFilename(file) {
const fileExtension = file.name.split('.').pop();
determineNetworkFilename(logoFile) {
const fileExtension = logoFile.name.split('.').pop();
const primaryNetworkName = prompt("Enter the name for the primary network (Usually 'Cigna' or 'MedCost':");
const secondaryNetworkName = prompt("Enter the name for the primary network (ex: Health Partners):");
const secondaryNetworkName = prompt("Enter the name for the partner network (ex: Health Partners):");
const logoFilename = this.titleizeText(primaryNetworkName).concat(this.titleizeText(secondaryNetworkName)).concat("Logo.").concat(fileExtension).replaceAll(' ', '');
return logoFilename
}
determineEmployerFilename(file) {
const fileExtension = file.name.split('.').pop();
const employerName = prompt("Enter the name for the new Employer (minus any 'The's, 'LLC', or 'Health Plan'):");
determineEmployerFilename(logoFile) {
const fileExtension = logoFile.name.split('.').pop();
const employerName = this.employerNameValue
const logoFilename = this.titleizeText(employerName).concat("Logo.").concat(fileExtension).replaceAll(' ', '');
return logoFilename
@@ -0,0 +1,25 @@
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["providerNetworkField", "networkLogoField", "providerSectionField"]
connect() {
console.log("---provider update---")
}
syncDefaults() {
const pnValue = this.providerNetworkFieldTarget.value
if (pnValue == "Cigna") {
this.networkLogoFieldTarget.value = 1
this.providerSectionFieldTarget.value = 30
} else if (pnValue == "Medcost") {
this.networkLogoFieldTarget.value = 2
this.providerSectionFieldTarget.value = 26
} else {
this.networkLogoFieldTarget.value = ""
this.providerSectionFieldTarget.value = ""
}
const event = new Event('change', { bubbles: true });
this.networkLogoFieldTarget.dispatchEvent(event);
}
}
+118
View File
@@ -0,0 +1,118 @@
class ProcessMemberCardDataJob < ApplicationJob
queue_as :default
def perform(member_key, member_card_exceptions_attrs, has_divisions = false, has_dental = false)
member = Member.find_by(pb_entity_key: member_key)
effect_date = determine_eff_date(member)
if effect_date
member_card = @base_card.dup
member_attributes = {
full_name: member.id_card_display_name,
full_name_last_name_first: member.name,
primary_mb_member_key: member.pb_entity_key,
family_id: member.family_id,
plan_id: member.id_card_plan_id,
medical_eff_date: effect_date.strftime("%m/%d/%Y")
}
if member.dependents.present?
dependent_attributes = format_dependent_attributes(member)
member_attributes.merge!(dependent_attributes)
end
if has_divisions
member_attributes.merge!({employer_name: member.division})
end
if member_card_exceptions_attrs.present?
# exceptions_attributes = {}
# field_exceptions = IdCard::FieldException.where(id: field_exception_ids)
# member_exception_values = member.id_card_field_exception_values
# field_exceptions.each do |fe|
# if fe.exception_values.include?(member_exception_values[fe.exception_type.to_sym])
# fe.field_exception_items.each do |fei|
# if fei.field_value.present?
# exception_eff_date = Date.strptime(fei.field_value, "%m/%d/%Y")
# member_eff_date = Date.strptime(member_attributes[:medical_eff_date], "%m/%d/%Y")
# if exception_eff_date > member_eff_date
# exceptions_attributes[fei.field_name.to_sym] = fei.field_value
# end
# elsif fei.provider_section_id.present?
# provider_attributes = IdCard::ProviderSection.find(fei.provider_section_id).attributes.with_indifferent_access.slice(
# :provider_line_1, :provider_line_2, :provider_line_3, :provider_line_4, :provider_line_5, :provider_line_6,
# :provider_line_7, :provider_line_8, :provider_line_9, :provider_line_10, :provider_line_11, :provider_line_12,
# :claim_to_1, :claim_to_2, :claim_to_3, :claim_to_4, :claim_to_5, :claim_to_6,
# :claim_to_7, :claim_to_8, :claim_to_9, :claim_to_10, :claim_to_11, :claim_to_12
# )
# exceptions_attributes.merge!(provider_attributes)
# elsif fei.network_logo_id.present?
# exceptions_attributes.merge!(network_logo_filename: fei.network_logo.filename)
# end
# end
# end
# end
member_attributes.merge!(member_card_exceptions_attrs)
end
if has_dental
if member.dental_plan_key
member_attributes.merge!({dental_coverage: member.coverage_class.upcase})
unless member.id_card_plan_id
member_attributes.merge!({group_number: "", medical_eff_date: ""})
# dental_plan = IdCard::Plan.find_by(pb_product_key: 1025)
if IdCard::Plan.find_by(pb_product_key: member.dental_plan_key).blank?
member_attributes.merge!({employer_name: 'COBRA'})
end
end
end
end
if member.id_card_plan.present? && member.id_card_plan.title.upcase.include?('COBRA')
member_attributes.merge!({employer_name: 'COBRA'})
end
if member.id_card_plan_id.present?
member_card = IdCard::PrintData.find_by(pl_plan_key: member.pl_plan_key, plan_id: member.id_card_plan_id, primary_mb_member_key: nil).dup
else
member_card = IdCard::PrintData.where(pl_plan_key: member.pl_plan_key, primary_mb_member_key: nil).first.dup
end
member_card.assign_attributes(member_attributes)
member_card.save
# if dependent_attributes.present?
# dependent_card = member_card.dup
# dependent_card.full_name_last_name_first = dependent_card.full_name_last_name_first.concat(" dependent")
# dependent_card.save
# end
end
true
# BatchProcess.increment_counter(:completed_jobs, batch_process_id)
end
private
def determine_eff_date(member)
participation = Vhcs::PbProductParticipation.joins('INNER JOIN "PBCoveredEntities" ON "PBProductParticipation"."PBProductParticipationKey" = "PBCoveredEntities"."PBProductParticipationKey"').where('"PBCoveredEntities"."PBEntityKey" = ?', member.pb_entity_key).order(out_of_effect: :desc).first
in_effect = participation.in_effect
out_of_effect = participation.out_of_effect
if in_effect <= (Date.today + 90.days) && (out_of_effect - 1.day) > Date.today && out_of_effect > in_effect
in_effect
else
false
end
end
def format_dependent_attributes(member)
dependent_attributes = {}
member.dependents.each_with_index do |dep, index|
dependent_attributes["dependent_#{index + 1}".to_sym] = dep
end
dependent_attributes
end
end
+138
View File
@@ -0,0 +1,138 @@
class UpdateEmployerJob < ApplicationJob
queue_as :default
def perform(employer_identifier: {}, employer_plan_header: {}, full_sync: false)
if employer_plan_header.present?
pl_plan_key = employer_plan_header['PLPlanKey'].to_s
employer_identifier[:pl_plan_key] = pl_plan_key
elsif employer_identifier[:group_number]
group_number = employer_identifier[:group_number]
pl_plan_key = Vhcs::PlPlanGroupCode.find_by(group_code: group_number).pl_plan_key
elsif employer_identifier[:pl_plan_key]
pl_plan_key = employer_identifier[:pl_plan_key]
end
if pl_plan_key.present?
if employer_plan_header.empty?
sql_query = "SELECT PLPlanKey, PlanId, ShortDesc FROM PLPlanHeader WHERE PLPlanKey = #{pl_plan_key}"
employer_plan_header = VhcsRecord.connection.select_all(sql_query).first
end
puts "== Updating #{employer_plan_header['ShortDesc'].strip.titleize} =="
plan_code = Vhcs::HlPlanCode.find_by(plan_key: pl_plan_key)
pb_company_plan = Vhcs::PbCompanyPlans.find_by(pl_plan_key: pl_plan_key)
employer = Employer.find_or_create_by!(employer_identifier)
id_card_setup = employer.id_card_setup || employer.create_id_card_setup!(pl_plan_key: employer.pl_plan_key)
full_sync = employer.previously_new_record? || full_sync
unless group_number.present?
group_number = Vhcs::PlPlanGroupCode.find_by(pl_plan_key: pl_plan_key).group_code
end
employer_update_attrs = {}
employer_update_attrs.merge!({
plan_id: employer_plan_header['PlanId'].strip.to_i,
company_pb_entity_key: pb_company_plan.company_pb_entity_key,
group_number: group_number,
pl_plan_key: pl_plan_key
})
if plan_code.present? && employer.effective_date.blank?
employer_update_attrs.merge!({
effective_date: plan_code.effect_date.strftime("%m/%d/%Y")
})
end
if full_sync && employer.name.blank?
employer_update_attrs.merge!({
name: employer_plan_header['ShortDesc'].strip.titleize
})
end
employer.update(employer_update_attrs)
if [employer.pl_plan_key, employer.group_number, employer.company_pb_entity_key, employer.plan_id].all?(&:present?)
employer.update(active: true)
end
setup_update_attrs = {}
if plan_code.present? && id_card_setup.rx_group_number.blank?
setup_update_attrs.merge!({
rx_group_number: plan_code.medical_number
})
end
if full_sync
setup_update_attrs.merge!({
print_name: determine_card_print_name(pb_company_plan.company_pb_entity_key, pl_plan_key)
})
end
id_card_setup.update(setup_update_attrs)
# plan_code = Vhcs::HlPlanCode.find_by(plan_key: employer.pl_plan_key)
# employer.group_number = plan_code.group_number
# id_card_setup.rx_group_number = plan_code.medical_number
# employer.effective_date = plan_code.effect_date.strftime("%m/%d/%Y")
# pb_company_plan = Vhcs::PbCompanyPlans.find_by(pl_plan_key: employer.pl_plan_key)
# employer.company_pb_entity_key = pb_company_plan.company_pb_entity_key
# card_print_name = Vhcs::PbEntity.where(company_pb_entity_key: employer.company_pb_entity_key, entity_type_id: 1007).last.last_name
# id_card_setup.print_name = card_print_name
# if employer.up_to_date?
# employer.active = true
# end
# employer.default_network_logo = determine_network_logos(employer.pl_plan_key)
# plan_codes = Vhcs::HlEgglestonCardBenefit.where(plan_key: employer.pl_plan_key).pluck(:plan_id).uniq
# employer_plans = employer.id_card_setup.plans
# plan_titles = employer_plans.pluck(:title)
# vhcs_plans = Vhcs::PbProduct.where(company_pb_entity_key: pb_company_plan.company_pb_entity_key, is_active: 255)
# vhcs_plans.each do |vp|
# if employer_plans.present? && plan_titles.all?(&:present?) && employer_plans.find_by(pb_product_key: vp.pb_product_key).nil?
# plan_title_matcher = Amatch::JaroWinkler.new(vp.short_description)
# closest_title = plan_titles.max_by { |title| plan_title_matcher.match(title) }
# plan = employer_plans.find_or_create_by(title: closest_title)
# plan.update(
# title: vp.short_description,
# pb_product_key: vp.pb_product_key,
# pl_plan_key: employer.pl_plan_key
# )
# plan_titles.delete(closest_title)
# elsif employer_plans.blank?
# employer_plans.create!(
# pb_product_key: vp.pb_product_key,
# title: vp.short_description,
# pl_plan_key: employer.pl_plan_key
# )
# # plan.update(
# # title: vp.short_description,
# # pl_plan_key: employer.pl_plan_key
# # )
# end
# end
end
employer.presence
end
private
def determine_card_print_name(company_pb_entity_key, pl_plan_key)
card_print_names = Vhcs::PbEntity.where(company_pb_entity_key: company_pb_entity_key, entity_type_id: 1007)
.where.not("LastName LIKE ? OR LastName LIKE ? OR LastName LIKE ?", "%COBRA%", "Active", ".%").pluck(:last_name)
if pl_plan_key == "2"
"sm ART"
elsif card_print_names.count > 2
Employer.employer_trim_name(card_print_names.first)
else
card_print_names.last
end
end
end
+67
View File
@@ -0,0 +1,67 @@
class UpdateEmployerPlansJob < ApplicationJob
queue_as :default
def perform(pl_plan_key)
employer = Employer.includes(:id_card_setup).find_by(pl_plan_key: pl_plan_key)
setup = employer.id_card_setup
puts "== Updating #{employer.name} Plans =="
pb_company_plan = Vhcs::PbCompanyPlans.find_by(pl_plan_key: pl_plan_key)
vhcs_card_plans = Vhcs::PbProduct.where(company_pb_entity_key: pb_company_plan.company_pb_entity_key, is_active: 255).where.not("ShortDescription LIKE ?", "%Vision%")
unless setup.has_dental
vhcs_card_plans = vhcs_card_plans.where.not("ShortDescription LIKE ?", "%Dental%")
end
vhcs_card_plan_product_keys = vhcs_card_plans.pluck(:pb_product_key)
vhcs_card_plan_titles = vhcs_card_plans.pluck(:short_description).map(&:strip)
employer_plans = employer.id_card_setup.plans
employer_plan_product_keys = employer_plans.pluck(:pb_product_key)
employer_plan_titles = employer_plans.pluck(:title)
plans_without_product_key = employer_plans.where(pb_product_key: ["", nil])
new_card_plan_pb_product_keys = vhcs_card_plan_product_keys - employer_plan_product_keys
vhcs_card_plans_to_import = Vhcs::PbProduct.where(pb_product_key: new_card_plan_pb_product_keys)
vhcs_card_plans_to_import.each do |vhcs_plan_import|
# if employer_plans.present? && plan_titles.all?(&:present?) && employer_plans.find_by(pb_product_key: vhcs_plan.pb_product_key).nil?
# if employer_plans.find_by(pb_product_key: vhcs_plan.pb_product_key).nil?
if plans_without_product_key
plan_title_matcher = Amatch::JaroWinkler.new(vhcs_plan_import.short_description.strip)
title_match = employer_plan_titles.max_by { |title| plan_title_matcher.match(title) }
plan = employer_plans.find_or_create_by(title: title_match)
plan.update(
pb_product_key: vhcs_plan_import.pb_product_key,
title: vhcs_plan_import.short_description.strip,
pl_plan_key: employer.pl_plan_key
)
employer_plan_titles.delete(title_match)
else
employer_plans.create!(
pb_product_key: vhcs_plan_import.pb_product_key,
title: vhcs_plan_import.short_description.strip,
pl_plan_key: employer.pl_plan_key
)
end
end
employer
end
private
def determine_card_print_name(company_pb_entity_key, pl_plan_key)
card_print_names = Vhcs::PbEntity.where(company_pb_entity_key: company_pb_entity_key, entity_type_id: 1007)
.where.not("LastName LIKE ? OR LastName LIKE ? OR LastName LIKE ?", "%COBRA%", "Active", ".%").pluck(:last_name)
if pl_plan_key == "2"
"sm ART"
elsif card_print_names.count > 2
Employer.employer_trim_name(card_print_names.first)
else
card_print_names.last
end
end
end
+104
View File
@@ -0,0 +1,104 @@
class UpdateMemberJob < ApplicationJob
queue_as :default
def perform(pb_entity_key, employer_id, has_divisions = false, has_dental = false, vw_mb_member = {})
unless vw_mb_member.present?
vw_mb_member = Vhcs::VwmbMember.find_by(enrollee_type_value_id: 1, pb_entity_key: pb_entity_key).attributes.with_indifferent_access.slice(:mb_member_key, :pb_entity_key, :pl_plan_key, :family_id, :full_name_last_name_first, :social_security_number)
end
pb_products = Vhcs::PbProduct.joins('
INNER JOIN "PBProductAvailability" ON "PBProductAvailability"."PBProductKey" = "PBProduct"."PBProductKey"
INNER JOIN "PBProductParticipation" ON "PBProductParticipation"."PBProductAvailabilityKey" = "PBProductAvailability"."PBProductAvailabilityKey"
INNER JOIN "PBCoveredEntities" ON "PBProductParticipation"."PBProductParticipationKey" = "PBCoveredEntities"."PBProductParticipationKey"
').where('
"PBCoveredEntities"."PBEntityKey" = ?
AND "PBProductParticipation"."InEffect" <= ?
AND "PBProductParticipation"."OutOfEffect" > ?',
vw_mb_member[:pb_entity_key], 2.month.from_now , 1.day.ago
)
if pb_products.present? && vw_mb_member[:social_security_number].present?
member = Member.find_or_create_by!(pb_entity_key: vw_mb_member[:pb_entity_key], employer_id: employer_id)
member.name = vw_mb_member[:full_name_last_name_first].titleize
member.mb_member_key = vw_mb_member[:mb_member_key]
member.family_id = vw_mb_member[:family_id]
member.pl_plan_key = vw_mb_member[:pl_plan_key]
card_display_name = Vhcs::PbEntity.find_by(pb_entity_key: member.pb_entity_key).full_name
member.id_card_display_name = card_display_name
if has_divisions
division = Vhcs::PbEntity.joins('
INNER JOIN "PBAffiliation" ON "PBAffiliation"."ParentPBEntityKey" = "PBEntity"."PBEntityKey"
INNER JOIN "PBProductParticipation" ON "PBProductParticipation"."PBAffiliationKey" = "PBAffiliation"."PBAffiliationKey"
INNER JOIN "PBCoveredEntities" ON "PBProductParticipation"."PBProductParticipationKey" = "PBCoveredEntities"."PBProductParticipationKey"
').find_by('
"PBCoveredEntities"."PBEntityKey" = ?
AND "PBProductParticipation"."OutOfEffect" > ?',
member.pb_entity_key, 1.day.ago
).last_name
member.division = division
end
if has_dental
medical_pb_product_key = pb_products.where("ShortDescription LIKE ?", "%Medical%")&.first&.pb_product_key
dental_pb_product_key = pb_products.where("ShortDescription LIKE ?", "%Dental%")&.first&.pb_product_key
# dental_pb_product_key = pb_products.where(short_description: "Dental")&.first&.pb_product_key
if dental_pb_product_key
member.dental_plan_key = dental_pb_product_key
coverage_class = Vhcs::GenLookupTables.joins('
INNER JOIN "PBProductParticipation" ON "PBProductParticipation"."CoverageTypeCode" = "GEN_LookupTables"."RecordID"
INNER JOIN "PBCoveredEntities" ON "PBProductParticipation"."PBProductParticipationKey" = "PBCoveredEntities"."PBProductParticipationKey"
INNER JOIN "PBProductAvailability" ON "PBProductAvailability"."PBProductAvailabilityKey" = "PBProductParticipation"."PBProductAvailabilityKey"
INNER JOIN "PBProduct" ON "PBProduct"."PBProductKey" = "PBProductAvailability"."PBProductKey"
').find_by('
"PBCoveredEntities"."PBEntityKey" = ?
AND "PBProductParticipation"."InEffect" <= ?
AND "PBProductParticipation"."OutOfEffect" > ?
AND "PBProduct"."PBProductKey" = ?',
member.pb_entity_key, 1.month.from_now, 1.day.ago, dental_pb_product_key
).short_desc
member.coverage_class = coverage_class
end
else
medical_pb_product_key = pb_products.first.pb_product_key
end
if medical_pb_product_key && plan = IdCard::Plan.find_by(pb_product_key: medical_pb_product_key)
member.id_card_plan = plan
end
member.dependents = get_dependent_names_by_sequence(member)
# if employer_members_update
# member
# else
# end
puts "---- #{member.name}"
end
member.presence
end
private
def get_dependent_names_by_sequence(member)
dependents = Vhcs::VwmbMember.joins('
INNER JOIN "PBCoveredEntities" ON "PBCoveredEntities"."PBEntityKey" = "vwMBMember"."PBEntityKey"
INNER JOIN "PBProductParticipation" ON "PBProductParticipation"."PBProductParticipationKey" = "PBCoveredEntities"."PBProductParticipationKey"
INNER JOIN "PBProductAvailability" ON "PBProductAvailability"."PBProductAvailabilityKey" = "PBProductParticipation"."PBProductAvailabilityKey"
INNER JOIN "PBProduct" ON "PBProduct"."PBProductKey" = "PBProductAvailability"."PBProductKey"
').where('
"EnrolleeTypeKey" != 1044 AND "PLPlanKey" = ? AND "PBProductParticipation"."OutOfEffect" >= ? AND "FamilyID" = ?', member.pl_plan_key, Date.today.strftime("%m/%d/%Y"), member.family_id
)
if member.pl_plan_key == 3
dependents = dependents.where('"PBProduct"."PBProductKey" != 1024')
elsif member.pl_plan_key == 2
dependents = dependents.where('"PBProduct"."PBProductKey" != 1019')
end
dependent_names = dependents.order(:sequence_number).map { |dep| dep.first_name + ' ' + dep.last_name}.uniq
dependent_names
end
end
+5
View File
@@ -0,0 +1,5 @@
class BatchProcess < ApplicationRecord
end
-4
View File
@@ -1,4 +0,0 @@
class CardLogoFile < ApplicationRecord
has_many :employer_card_logos, dependent: :destroy
has_many :employers, through: :employer_card_logos
end
-3
View File
@@ -1,3 +0,0 @@
class CardProvider < ApplicationRecord
has_many :employers
end
-3
View File
@@ -1,3 +0,0 @@
class CardRx < ApplicationRecord
has_many :employers
end
+153
View File
@@ -0,0 +1,153 @@
module EmployerAutomation
extend ActiveSupport::Concern
included do
scope :uninitialized, -> {
where(initialized: false)
}
scope :initialized, -> {
where(initialized: true)
}
scope :not_automation_ready, -> {
where(group_number: [nil, ''])
}
scope :automation_ready, -> {
where.not(group_number: [nil, ''])
}
scope :in_automation_initilization, -> {
joins(:id_card_setup)
.where(initialized: false)
.or(
where(id_card_setup: {initialized: false})
)
}
# scope :missing_keychain_values, -> {
# where(company_pb_entity_key: [nil, ''])
# .or(where(plan_id: [nil, '']))
# .or(where(group_number: [nil, '']))
# .or(where(pl_plan_key: [nil, '']))
# }
scope :missing_keychain_initialization, -> {
uninitialized.automation_ready
}
scope :uninitialized_id_card_setup, -> {
joins(:id_card_setup)
.where(id_card_setup: {initialized: false})
}
scope :missing_plans, -> {
where.missing(:plans)
.or(
where(
id: joins(:plans)
.where(plans: { pb_product_key: [nil, ''] })
.select(:id)
)
)
}
scope :has_plans, -> {
where.associated(:plans)
.where.not(
id: joins(:plans)
.where(plans: { pb_product_key: [nil, ''] })
.select(:id)
).distinct
}
scope :missing_plans_initialization, -> {
uninitialized_id_card_setup.missing_plans
}
scope :missing_members_initialization, -> {
uninitialized_id_card_setup.has_plans
}
scope :with_active_id_card_setup, -> {
active.left_outer_joins(:id_card_setup)
.where(id_card_setup: {active: true})
}
# scope :with_keychain_values, -> {
# where.not(
# pl_plan_key: [nil, ''],
# group_number: [nil, ''],
# company_pb_entity_key: [nil, ''],
# plan_id: [nil, '']
# )
# }
scope :deactivated, -> {
inactive.initialized
}
# Employer.joins(:id_card_setup)
# .left_outer_joins(:plans)
# .where(plans: { pb_product_key: [nil, ''] })
# .group('users.id') # Group by user ID
# .having('COUNT(posts.id) = 0')
# Employer.left_outer_joins(:plans)
# .where(plans: { id: nil })
# .or(Employer.where(plans: { pb_product_key: [nil, ''] }))
# Employer.where.missing(:plans)
# .or(Employer.joins(:plans).where(plans: { pb_product_key: [nil, ''] }))
# Employer.joins(id_card_setup: :plans).where.not("plans.id_card_setup_id = id_card_setup.id").or
# (where(plans: { pb_product_key: [nil, ''] }))
# scope :with_survey_and_no_questions, -> {
# joins(:survey) # join has_one
# .left_joins(survey: :questions) # join has_many through has_one
# .where(questions: { id: nil }) # filter where has_many is empty
# }
# scope :missing_initial_members, -> {
# new_groups.with_plans
# }
end
# class_methods do
# # Methods in this block become class methods of the including class.
# def count_all_visible
# visible.count
# end
# end
# Any other methods defined here become instance methods automatically.
# def up_to_date?
# self.pl_plan_key.present? &&
# self.company_pb_entity_key.present? &&
# self.plan_id.present? &&
# self.group_number.present? &&
# self.effective_date.present?
# end
def sync_members_with_vhcs
AutomationService::EmployerMembersUpdate.new(pl_plan_key).call
end
def sync_plans_with_vhcs
AutomationService::EmployerPlansUpdate.new(pl_plan_key).call
end
def automation_identifier
attributes.with_indifferent_access.slice(
pl_plan_key.present? ? :pl_plan_key : :group_number
)
end
def sync_with_vhcs
employer_identifier = automation_identifier
AutomationService::EmployerUpdate.new(employer_identifier).call
end
end
+30
View File
@@ -0,0 +1,30 @@
module MemberAutomation
extend ActiveSupport::Concern
# included do
# # Code in this block becomes instance methods or class macros (like scopes, validations, associations) in the including class.
# scope :visible, -> { where(visible: true) }
# scope :invisible, -> { where(visible: false) }
# validates :status, inclusion: { in: %w(visible invisible), message: "%{value} is not a valid status" }
# end
# class_methods do
# # Methods in this block become class methods of the including class.
# def count_all_visible
# visible.count
# end
# end
# Any other methods defined here become instance methods automatically.
# def up_to_date?
# self.pl_plan_key.present? &&
# self.company_pb_entity_key.present? &&
# self.plan_id.present? &&
# self.group_number.present? &&
# self.effective_date.present?
# end
def sync_with_vhcs
AutomationService::MemberUpdate.new(self.employer.pl_plan_key, self.pb_entity_key).call
end
end
+43 -86
View File
@@ -1,105 +1,63 @@
class Employer < ApplicationRecord
has_many :members
has_many :plans, dependent: :destroy
accepts_nested_attributes_for :plans, allow_destroy: true, reject_if: :all_blank
has_many :alternate_network_logos, dependent: :destroy
accepts_nested_attributes_for :alternate_network_logos, allow_destroy: true, reject_if: :all_blank
has_many :employer_card_logos, dependent: :destroy
accepts_nested_attributes_for :employer_card_logos
has_many :card_logo_files, through: :employer_card_logos
has_one :employer_brand_logo, -> { where(logo_type: 'employer') },
class_name: 'EmployerCardLogo',
dependent: :destroy
has_one :employer_logo, through: :employer_brand_logo, source: :card_logo_file
has_many :network_images, -> { where(logo_type: 'network') },
class_name: 'EmployerCardLogo',
dependent: :destroy
has_many :network_logos, through: :network_images, source: :card_logo_file
belongs_to :card_provider, optional: true
belongs_to :card_rx, optional: true
include EmployerAutomation
has_many :members, dependent: :destroy
accepts_nested_attributes_for :members, allow_destroy: true, reject_if: :all_blank
has_one :id_card_setup, class_name: 'IdCard::Setup', dependent: :destroy
has_many :plans, class_name: 'IdCard::Plan', through: :id_card_setup
scope :active, -> { where(active: true) }
scope :inactive, -> { where(active: false) }
before_save :create_slug, if: :will_save_change_to_name?
before_save :active_initialized_check, if: :will_save_change_to_active?
# before_save :process_employer_logo
# before_save :process_employer_logo, if: :employer_logo_filename_changed?
before_save :create_slug, if: :new_record?
after_save :process_employer_logo, if: :saved_change_to_employer_logo_filename?
def process_employer_logo
# if self.employer_logo.present? && !self.employer_logo.is_a?(String)
# self.card_logo_files.new(
# filename: self.employer_logo.filename,
# logo_type: 'employer',
# image: self.employer_logo.data,
# pl_plan_key: self.pl_plan_key || ""
# )
# end
if self.employer_logo_filename.present? && self.employer_logo_filename.is_a?(String)
image_file = CardLogoFile.find_by(filename: self.employer_logo_filename)
if image_file.present?
if self.employer_brand_logo.present?
self.employer_brand_logo.update(card_logo_file: image_file)
else
self.create_employer_brand_logo(card_logo_file: image_file, logo_type: 'employer')
end
end
def create_slug
self.slug = Employer.employer_trim_name(name).parameterize
end
def active_initialized_check
if active
self.initialized = true
end
if active == false
id_card_setup&.update(active: false)
end
end
def create_slug
self.slug = employer_trim_name(self.name).parameterize
def id_card_enabled?
self.id_card_setup.present?
end
def claims_check_enabled?
false
end
def employer_member_keys
{
pl_plan_key: self.pl_plan_key,
member_keys: self.members.pluck(:pb_entity_key)
}
end
def name_to_logo_filename(extension)
self.employer_trim_name(self.name).titleize.gsub(/\s+/, '').concat('Logo').concat(extension.downcase)
Employer.employer_trim_name(self.name).titleize.gsub(/[^a-zA-Z]/, '').concat('Logo').concat(extension.downcase)
end
def employer_trim_name(name)
regex_source = Regexp.union(["health", "plan", "the", "inc", "llc"]).source
def self.employer_trim_name(employer_name)
# employer_name = name.present? ? name : self.name
regex_source = Regexp.union(["health ", "plan", "the", "inc", "llc", "group"]).source
case_insensitive_regex = Regexp.new(regex_source, "i")
name.gsub(case_insensitive_regex, "").squish
employer_name.gsub(case_insensitive_regex, "").gsub(/[^[:alpha:][:space:]]/, "").squish
end
def self.permitted_params(params)
params.require(:employer).permit(
:name,
:slug,
:group_number,
:pl_plan_key,
:effective_date,
:employer_logo_filename,
:network_provider,
:default_network_logo,
:single_card_template,
:card_provider_id,
:card_rx_id,
plans_attributes: [
:id,
:title,
:pb_product_key,
:_destroy,
plan_benefits_attributes: [
:id,
:benefit_desc,
:benefit,
:sequence,
:_destroy,
]
],
alternate_network_logos_attributes: [
:id,
:network_logo,
:exception_type,
:exception_value,
:_destroy
]
:effective_date
)
end
@@ -111,24 +69,23 @@ class Employer < ApplicationRecord
medical_number: self.group_number,
dental_number: '',
plan_key: self.pl_plan_key,
effect_date: self.effective_date
effect_date: DateTime.strptime(self.effective_date, "%m/%d/%y")
)
# Replace fairos_info with template like for benefits
fairos_info = Vhcs::HlrxCrosRef.where(pl_plan_key: 52).first
rx_info = self.id_card_setup.rx_section
Vhcs::HlrxCrosRef.create!(
group_no: self.group_number,
rx_group_id: self.group_number,
help_desk: fairos_info.help_desk,
customer_service: fairos_info.customer_service,
web_url: fairos_info.web_url,
help_desk: rx_info.help_desk,
customer_service: rx_info.customer_service,
web_url: rx_info.web_url,
pl_plan_key: self.pl_plan_key
)
self.plans.each_with_index do |plan, i|
self.id_card_setup.plans.each_with_index do |plan, i|
plan.plan_benefits.each do |bene|
Vhcs::HlEgglestonCardBenefit.create!(
plan_id: plan.plan_id,
plan_id: plan.pb_product_key,
benefit_desc: bene.benefit_desc,
benefit: bene.benefit,
sequence: bene.sequence,
+5
View File
@@ -0,0 +1,5 @@
module IdCard
def self.table_name_prefix
"id_card_"
end
end
+50
View File
@@ -0,0 +1,50 @@
module IdCard
class EmployerLogo < ApplicationRecord
# before_validation :resize_logo, if: :image_data_changed?
# before_validation :calculate_aspect_ratio, if: :image_data_changed?
before_validation :process_image, if: :image_data_changed?
private
def process_image
image = Vips::Image.new_from_buffer(self.image_data, "")
resized_image = ImageProcessing::Vips
.source(image)
.resize_to_limit(nil, 400)
processed_image = resized_image.convert("png").call
new_image_data = processed_image.read
if new_image_data
self.image_data = new_image_data
self.filename = File.basename(self.filename, File.extname(self.filename)) + ".png"
self.content_type = "image/png"
end
image_ratio = image.width.to_f / image.height
if image_ratio
self.aspect_ratio = image_ratio.round(2)
end
end
# def resize_logo
# image = Vips::Image.new_from_buffer(self.image_data, "")
# processed_image = ImageProcessing::Vips
# .source(image)
# .resize_to_limit(nil, 200)
# .call
# self.image_data = processed_image.read
# end
# def calculate_aspect_ratio
# image_io = StringIO.new(self.image_data)
# width, height = FastImage.size(image_io)
# image_ratio = width.to_f / height
# if image_ratio
# self.aspect_ratio = image_ratio.round(2)
# end
# end
end
end
+51
View File
@@ -0,0 +1,51 @@
module IdCard
class FieldException < ApplicationRecord
belongs_to :setup
has_many :field_exception_items, dependent: :destroy
accepts_nested_attributes_for :field_exception_items, allow_destroy: true, reject_if: :all_blank
serialize :exception_values, coder: JSON
VALID_TYPES = ['family_id', 'zipcode', 'state'].freeze
before_validation :format_exception_values, if: :exception_values_changed?
validates :exception_type, inclusion: { in: VALID_TYPES,
message: "%{value} is not a valid exception type" }
def to_card_attrs
self.field_exception_items.map(&:card_attrs).reduce({}, :merge)
end
class << self
def permitted_params(params)
params.require(:id_card_setup).permit(
field_exceptions_attributes: [
:exception_type,
:exception_values,
:_destroy,
field_exception_items_attributes: [
:field_name,
:field_value,
:network_logo_id,
:provider_section_id,
:_destroy
]
]
)
end
end
private
def format_exception_values
if self.exception_values.is_a?(String)
self.exception_values = self.exception_values.split(",").map(&:strip)
end
end
end
end
@@ -0,0 +1,43 @@
module IdCard
class FieldExceptionItem < ApplicationRecord
belongs_to :field_exception
belongs_to :network_logo, optional: true
belongs_to :provider_section, optional: true
validate :only_one_exception_field_present
FIELDS_TO_VALIDATE = [:field_value, :network_logo_id, :provider_section_id].freeze
VALID_FIELD_NAMES = ['network_logo', 'provider_section', 'medical_eff_date']
validates :field_name, inclusion: { in: VALID_FIELD_NAMES,
message: "%{value} is not a valid Id Card Field Name" }
def card_attrs
case self.field_name
when "network_logo"
{"network_logo_filename" => IdCard::NetworkLogo.find(self.network_logo_id).filename}
when "provider_section"
IdCard::ProviderSection.find(self.provider_section_id).attributes.with_indifferent_access.slice(
:provider_line_1, :provider_line_2, :provider_line_3, :provider_line_4, :provider_line_5, :provider_line_6,
:provider_line_7, :provider_line_8, :provider_line_9, :provider_line_10, :provider_line_11, :provider_line_12,
:claim_to_1, :claim_to_2, :claim_to_3, :claim_to_4, :claim_to_5, :claim_to_6,
:claim_to_7, :claim_to_8, :claim_to_9, :claim_to_10, :claim_to_11, :claim_to_12
)
when "medical_eff_date"
{"medical_eff_date" => self.field_value}
end
end
private
def only_one_exception_field_present
present_fields = FIELDS_TO_VALIDATE.count { |field| self[field].present? }
if present_fields != 1
errors.add(:base, "Only one exception field can be present at a time")
end
end
end
end
+65
View File
@@ -0,0 +1,65 @@
module IdCard
class NetworkLogo < ApplicationRecord
# before_validation :resize_logo, if: :image_data_changed?
# before_validation :calculate_aspect_ratio, if: :image_data_changed?
before_validation :process_image, if: :image_data_changed?
scope :defaults, -> { where(default: true) }
class << self
def medcost
defaults.where("filename LIKE ?", "%MedCost%")
end
def cigna
defaults.where("filename LIKE ?", "%Cigna%")
end
end
private
def process_image
image = Vips::Image.new_from_buffer(self.image_data, "")
resized_image = ImageProcessing::Vips
.source(image)
.resize_to_limit(nil, 400)
processed_image = resized_image.convert("png").call
new_image_data = processed_image.read
if new_image_data
self.image_data = new_image_data
self.filename = File.basename(self.filename, File.extname(self.filename)) + ".png"
self.content_type = "image/png"
end
image_ratio = image.width.to_f / image.height
if image_ratio
self.aspect_ratio = image_ratio.round(2)
end
end
# def resize_logo
# image = Vips::Image.new_from_buffer(self.image_data, "")
# processed_image = ImageProcessing::Vips
# .source(image)
# .resize_to_limit(nil, 400)
# .call
# self.image_data = processed_image.read
# end
# def calculate_aspect_ratio
# image_io = StringIO.new(image_data)
# width, height = FastImage.size(image_io)
# image_ratio = width.to_f / height
# if image_ratio
# self.aspect_ratio = image_ratio.round(2)
# end
# end
end
end
+76
View File
@@ -0,0 +1,76 @@
module IdCard
class Plan < ApplicationRecord
belongs_to :setup, optional: true
has_many :plan_benefits, dependent: :destroy
accepts_nested_attributes_for :plan_benefits, allow_destroy: true, reject_if: :all_blank
scope :templates, -> { where(template: true) }
FARIOS_BENEFIT_FIELDS = ["Primary Visit", "Specialist Visit", "Urgent Care", "INN-Ind Ded", "INN-Family Ded", "OON-Ind Ded", "OON-Family Ded", "Co-Insurance", "INN-Ind OOP", "INN-Family OOP", "OON-Ind OOP", "OON-Family OOP", "Emergency Room", "Preventive Care"].freeze
TANDEMLOC_BENEFIT_FIELDS = ["Physician Visit", "Specialist Visit", "Urgent Care", "Deductible", "Co-Insurance", "Out-of-Pocket", "Emergency Room", "Preventive Care"].freeze
SMART_BENEFIT_FIELDS = [].freeze
after_initialize :build_plan_benefits, if: :new_record?
def build_plan_benefits
if plan_benefits.empty?
plan_benefit_fields = case setup&.card_template
when "TandemlocIDCard"
TANDEMLOC_BENEFIT_FIELDS
when "SmartIDCard"
SMART_BENEFIT_FIELDS
else
FARIOS_BENEFIT_FIELDS
end
plan_benefit_fields.each_with_index do |bene, i|
self.plan_benefits.build(benefit_desc: bene, sequence: (i + 1))
end
end
end
def format_template
formatted_title = title
if pl_plan_key.present?
employer_name = Employer.find_by(pl_plan_key: pl_plan_key).pluck(:name)
formatted_title.concat( " (#{employer_name})" )
end
{ id: id, title: formatted_title }
end
class << self
# def templates
# active_templates.map(&:format_template)
# end
def permitted_params(params)
params.require(:id_card_setup).permit(
plans_attributes: [
:id,
:title,
:pb_product_key,
:pl_plan_key,
:_destroy,
plan_benefits_attributes: [
:id,
:benefit_desc,
:benefit,
:sequence,
:_destroy,
]
]
)
end
end
private
def build_and_create_default_benefits
benefits = IdCardBenefitsTemplate.find_by(title: "BLANK").id_card_benefits.sort_by(&:sequence)
benefits.each do |ben|
id_card_plan_benefits.new(benefit_desc: ben.benefit_desc, sequence: ben.sequence)
end
end
end
end
+5
View File
@@ -0,0 +1,5 @@
module IdCard
class PlanBenefit < ApplicationRecord
belongs_to :plan
end
end
+15
View File
@@ -0,0 +1,15 @@
module IdCard
class PrintData < ApplicationRecord
STRING_ATTRIBUTES = %w[provider_line_1 provider_line_2 provider_line_3 provider_line_4 provider_line_5 provider_line_6 provider_line_7 provider_line_8 provider_line_9 provider_line_10 provider_line_11 provider_line_12 claim_to_1 claim_to_2 claim_to_3 claim_to_4 claim_to_5 claim_to_6 claim_to_7 claim_to_8 claim_to_9 claim_to_10 claim_to_11 claim_to_12 dependent_1 dependent_2 dependent_3 dependent_4 dependent_5 dependent_6 dependent_7 dependent_8 dental_coverage]
before_validation :assign_blank_strings_to_unassigned_params
def assign_blank_strings_to_unassigned_params
STRING_ATTRIBUTES.each do |attr|
# Use the blank? method which checks for nil, false, empty, or whitespace strings
self[attr] = "" if self[attr].blank?
end
end
end
end
+36
View File
@@ -0,0 +1,36 @@
module IdCard
class ProviderSection < ApplicationRecord
scope :defaults, -> { where(default: true) }
def self.permitted_params(params)
params.require(:id_card_setup).require(:provider_section).permit(
:provider_line_1,
:provider_line_2,
:provider_line_3,
:provider_line_4,
:provider_line_5,
:provider_line_6,
:provider_line_7,
:provider_line_8,
:provider_line_9,
:provider_line_10,
:provider_line_11,
:provider_line_12,
:claim_to_1,
:claim_to_2,
:claim_to_3,
:claim_to_4,
:claim_to_5,
:claim_to_6,
:claim_to_7,
:claim_to_8,
:claim_to_9,
:claim_to_10,
:claim_to_11,
:claim_to_12
)
end
end
end
+5
View File
@@ -0,0 +1,5 @@
module IdCard
class RxSection < ApplicationRecord
end
end
+103
View File
@@ -0,0 +1,103 @@
module IdCard
class Setup < ApplicationRecord
belongs_to :employer, class_name: 'Employer'
belongs_to :employer_logo, optional: true
belongs_to :network_logo, optional: true
belongs_to :provider_section, optional: true
belongs_to :rx_section, optional: true
has_many :plans, dependent: :destroy
has_many :field_exceptions, dependent: :destroy
accepts_nested_attributes_for :plans, allow_destroy: true, reject_if: :all_blank
accepts_nested_attributes_for :field_exceptions, allow_destroy: true, reject_if: :all_blank
attribute :queued_card_count, :integer, default: 0
scope :active, -> { where(active: true) }
FORM_COLORS = ['atmosphere', 'verdigris', 'bluemana', 'cobalt']
MODULE_COLOR = 'atmosphere'
before_save :active_initialized_check, if: :will_save_change_to_active?
def active_initialized_check
if active
self.initialized = true
end
end
# def employer_logo_filename
# self.employer_logo.filename
# end
# def network_logo_filename
# self.network_logo.filename
# end
def build_plan_with_default_benefits(attributes = {})
plan = plans.new(attributes)
benefits = IdCardBenefitsTemplate.find_by(title: "BLANK").id_card_benefits.sort_by(&:sequence)
benefits.each do |ben|
plan.plan_benefits.new(benefit_desc: ben.benefit_desc, sequence: ben.sequence)
end
plan
end
def has_field_exceptions?
self.field_exceptions.present?
end
def field_exceptions_card_attributes_by_member_id(member_array = nil)
unless member_array.present?
member_array = self.employer.members.pluck(:pb_entity_key)
end
card_fes = self.field_exceptions.includes(:field_exception_items).in_order_of(:exception_type, IdCard::FieldException::VALID_TYPES)
# fe_by_value = card_fes.in_order_of(:exception_type, IdCard::FieldException::VALID_TYPES).group_by(&:exception_type)
# .transform_values { |fes| fes.map { |fe| [fe.id, fe.exception_values] }.to_h }
# .compact_blank
# field_exception_types = card_fes.pluck(:exception_type).uniq
# if field_exception_types.include?("family_id")
# members = Member.where(pb_entity_key: member_array)
# end
# if field_exception_types.intersect?(["state", "zipcode"])
# member_addresses = Vhcs::PbEntityAddress.where(pb_entity_key: member_array)
# end
card_exceptions_map = {}
card_fes.each do |fe|
if fe.exception_type == "family_id"
matches = Member.where(pb_entity_key: member_array, family_id: fe.exception_values).pluck(:pb_entity_key)
elsif fe.exception_type == "zipcode"
matches = Vhcs::PbEntityAddress.where(pb_entity_key: member_array, zip: fe.exception_values).pluck(:pb_entity_key)
elsif fe.exception_type == "state"
matches = Vhcs::PbEntityAddress.where(pb_entity_key: member_array, state: fe.exception_values).pluck(:pb_entity_key)
end
if matches.present?
card_exceptions_map[fe.id] = fe.to_card_attrs
matches.each do |match|
unless card_exceptions_map[match].present?
card_exceptions_map[match] = fe.id
end
end
end
end
card_exceptions_map
end
def self.permitted_params(params)
params.require(:id_card_setup).permit(
:print_name,
:network_provider,
:card_template,
:rx_group_number,
:employer_logo_id,
:network_logo_id,
:rx_section_id,
:provider_section_id
)
end
end
end
+24 -1
View File
@@ -1,6 +1,29 @@
class Member < ApplicationRecord
belongs_to :plan
include MemberAutomation
belongs_to :id_card_plan, class_name: 'IdCard::Plan', optional: true
belongs_to :employer
serialize :dependents, coder: JSON
before_validation :format_dependents, if: :dependents_changed?
def id_card_field_exception_values
address = Vhcs::PbEntityAddress.find_by(pb_entity_key: self.pb_entity_key)
{
zipcode: address.zip,
state: address.state,
family_id: self.family_id
}
end
private
def format_dependents
if self.dependents.is_a?(String)
self.dependents = self.dependents.split(",").map(&:strip)
end
end
end
+14
View File
@@ -0,0 +1,14 @@
class CardLogoFile < ApplicationRecord
has_many :employer_card_logos, dependent: :destroy
has_many :employers, through: :employer_card_logos
before_save :round_aspect_ratio
private
def round_aspect_ratio
if self.aspect_ratio.present?
self.aspect_ratio = self.aspect_ratio.round(2)
end
end
end
-18
View File
@@ -1,18 +0,0 @@
class Plan < ApplicationRecord
belongs_to :employer
has_many :plan_benefits, dependent: :destroy
accepts_nested_attributes_for :plan_benefits, allow_destroy: true, reject_if: :all_blank
# after_initialize :create_default_benefits, if: :new_record?
private
def build_and_create_default_benefits
benefits = IdCardBenefitsTemplate.find_by(title: "BLANK").id_card_benefits.sort_by(&:sequence)
benefits.each do |ben|
plan_benefits.new(benefit_desc: ben.benefit_desc, sequence: ben.sequence)
end
end
end
-3
View File
@@ -1,3 +0,0 @@
class PlanBenefit < ApplicationRecord
belongs_to :plan
end
+5
View File
@@ -0,0 +1,5 @@
module Report
def self.table_name_prefix
"report_"
end
end
+4
View File
@@ -0,0 +1,4 @@
class Report::ComparisonError < ApplicationRecord
belongs_to :employer_card_comparison, optional: true
belongs_to :member_card_comparison, optional: true
end
@@ -0,0 +1,15 @@
module Report
class EmployerCardComparison < ApplicationRecord
has_many :comparison_errors, dependent: :destroy
accepts_nested_attributes_for :comparison_errors, allow_destroy: true, reject_if: :all_blank
has_many :member_card_comparisons
has_many :member_comparison_errors, through: :member_card_comparisons, source: :comparison_errors
def employer_total_errors
self.comparison_errors.count + self.member_comparison_errors.count
end
end
end
@@ -0,0 +1,9 @@
module Report
class MemberCardComparison < ApplicationRecord
has_many :comparison_errors, dependent: :destroy
accepts_nested_attributes_for :comparison_errors, allow_destroy: true, reject_if: :all_blank
belongs_to :employer_card_comparison, optional: true
end
end
+2
View File
@@ -0,0 +1,2 @@
class Report::OldCardDuplicate < ApplicationRecord
end
-14
View File
@@ -1,14 +0,0 @@
class SampleIdCard < ApplicationRecord
STRING_ATTRIBUTES = %w[provider_line_1 provider_line_2 provider_line_3 provider_line_4 provider_line_5 provider_line_6 provider_line_7 provider_line_8 provider_line_9 provider_line_10 provider_line_11 claim_to_1 claim_to_2 claim_to_3 claim_to_4 claim_to_5 claim_to_6 claim_to_7 claim_to_8 claim_to_9 claim_to_10 claim_to_11 dependent_1 dependent_2 dependent_3 dependent_4 dependent_5 dependent_6 dependent_7 dependent_8]
before_validation :assign_blank_strings_to_unassigned_params
def assign_blank_strings_to_unassigned_params
STRING_ATTRIBUTES.each do |attr|
# Use the blank? method which checks for nil, false, empty, or whitespace strings
self[attr] = "" if self[attr].blank?
end
end
end
+43
View File
@@ -0,0 +1,43 @@
module Vhcs
class GenLookupTables < VhcsRecord
self.table_name = 'GEN_LookupTables'
alias_attribute :record_id, :RecordID
alias_attribute :table_id, :TableID
alias_attribute :value_id, :ValueID
alias_attribute :company_pb_entity_key, :CompanyPBEntityKey
alias_attribute :short_desc, :ShortDesc
alias_attribute :long_desc, :LongDesc
alias_attribute :is_active, :IsActive
alias_attribute :is_default, :IsDefault
alias_attribute :is_bit_flag, :IsBitFlag
alias_attribute :is_company_specific, :IsCompanySpecific
alias_attribute :is_editable, :IsEditable
alias_attribute :long_description, :LongDescription
alias_attribute :sort_value, :SortValue
alias_attribute :system_id_bit_mask, :SystemIDBitMask
def attributes
rails_like = {
record_id: self.record_id,
table_id: self.table_id,
value_id: self.value_id,
company_pb_entity_key: self.company_pb_entity_key,
short_desc: self.short_desc,
long_desc: self.long_desc,
is_active: self.is_active,
is_default: self.is_default,
is_bit_flag: self.is_bit_flag,
is_company_specific: self.is_company_specific,
is_editable: self.is_editable,
long_description: self.long_description,
sort_value: self.sort_value,
system_id_bit_mask: self.system_id_bit_mask,
}
super.merge(rails_like)
end
end
end
+1 -1
View File
@@ -1,5 +1,5 @@
module Vhcs
class HLEggIdCardDependent < VhcsRecord
class HlEggIdCardDependent < VhcsRecord
self.table_name = 'HLEggIdCardDependent'
+219
View File
@@ -0,0 +1,219 @@
module Vhcs
class HlidCardEggData < VhcsRecord
self.table_name = 'HLIDCardEggData'
alias_attribute :id, :ID
alias_attribute :facility, :Facility
alias_attribute :employer_name, :Division
alias_attribute :full_name, :FullName
alias_attribute :ssn, :SSN
alias_attribute :medical_coverage, :MedicalCoverage
alias_attribute :medical_eff_date, :MedicalEffDate
alias_attribute :group_number, :MedicalGroupNum
alias_attribute :dental_coverage, :DentalCoverage
alias_attribute :dental_eff_date, :DentalEffDate
alias_attribute :dental_group_num, :DentalGroupNum
alias_attribute :card_type, :CardType
alias_attribute :provider_code, :ProviderCode
alias_attribute :provider_line_1, :ProviderLine1
alias_attribute :provider_line_2, :ProviderLine2
alias_attribute :provider_line_3, :ProviderLine3
alias_attribute :provider_line_4, :ProviderLine4
alias_attribute :provider_line_5, :ProviderLine5
alias_attribute :provider_line_6, :ProviderLine6
alias_attribute :provider_line_7, :ProviderLine7
alias_attribute :provider_line_8, :ProviderLine8
alias_attribute :provider_line_9, :ProviderLine9
alias_attribute :provider_line_10, :ProviderLine10
alias_attribute :provider_line_11, :ProviderLine11
alias_attribute :mail_to, :MailTo
alias_attribute :mail_to_2, :MailTo2
alias_attribute :claim_to_1, :ClaimTo1
alias_attribute :claim_to_2, :ClaimTo2
alias_attribute :claim_to_3, :ClaimTo3
alias_attribute :claim_to_4, :ClaimTo4
alias_attribute :claim_to_5, :ClaimTo5
alias_attribute :claim_to_6, :ClaimTo6
alias_attribute :claim_to_7, :ClaimTo7
alias_attribute :claim_to_8, :ClaimTo8
alias_attribute :claim_to_9, :ClaimTo9
alias_attribute :claim_to_10, :ClaimTo10
alias_attribute :claim_to_11, :ClaimTo11
alias_attribute :contact_line_1, :ContactLine1
alias_attribute :contact_line_2, :ContactLine2
alias_attribute :contact_line_3, :ContactLine3
alias_attribute :group_number, :GroupNumber
alias_attribute :family_id, :FamilyId
alias_attribute :group_no, :GroupNo
alias_attribute :rx_group, :RXGroupID
alias_attribute :help_desk, :HelpDesk
alias_attribute :customer_service, :CustomerService
alias_attribute :web_url, :WebUrl
alias_attribute :expr_1, :Expr1
alias_attribute :line_3, :Line3
alias_attribute :dependent_1, :Dependent1
alias_attribute :dependent_2, :Dependent2
alias_attribute :dependent_3, :Dependent3
alias_attribute :dependent_4, :Dependent4
alias_attribute :dependent_5, :Dependent5
alias_attribute :dependent_6, :Dependent6
alias_attribute :dependent_7, :Dependent7
alias_attribute :dependent_8, :Dependent8
alias_attribute :benefit_desc_1, :BenDesc1
alias_attribute :benefit_1, :Ben1
alias_attribute :benefit_desc_2, :BenDesc2
alias_attribute :benefit_2, :Ben2
alias_attribute :benefit_desc_3, :BenDesc3
alias_attribute :benefit_3, :Ben3
alias_attribute :benefit_desc_4, :BenDesc4
alias_attribute :benefit_4, :Ben4
alias_attribute :benefit_desc_5, :BenDesc5
alias_attribute :benefit_5, :Ben5
alias_attribute :benefit_desc_6, :BenDesc6
alias_attribute :benefit_6, :Ben6
alias_attribute :benefit_desc_7, :BenDesc7
alias_attribute :benefit_7, :Ben7
alias_attribute :benefit_desc_8, :BenDesc8
alias_attribute :benefit_8, :Ben8
alias_attribute :benefit_desc_9, :BenDesc9
alias_attribute :benefit_9, :Ben9
alias_attribute :benefit_desc_10, :BenDesc10
alias_attribute :benefit_10, :Ben10
alias_attribute :benefit_desc_11, :BenDesc11
alias_attribute :benefit_11, :Ben11
alias_attribute :benefit_desc_12, :BenDesc12
alias_attribute :benefit_12, :Ben12
alias_attribute :benefit_desc_13, :BenDesc13
alias_attribute :benefit_13, :Ben13
alias_attribute :benefit_desc_14, :BenDesc14
alias_attribute :benefit_14, :Ben14
alias_attribute :pl_plan_key, :PLPlanKey
alias_attribute :primary_mb_member_key, :PrimaryMBMemberKey
alias_attribute :ppo_lookup_1, :PPOLookup1
alias_attribute :ppo_lookup_2, :PPOLookup2
alias_attribute :precert_1, :Precert1
alias_attribute :precert_2, :Precert2
alias_attribute :precert_3, :Precert3
alias_attribute :precert_4, :Precert4
alias_attribute :precert_5, :Precert5
alias_attribute :precert_6, :Precert6
alias_attribute :misc_data, :MiscData
alias_attribute :ppo_data, :PPOData
alias_attribute :ppo_data_2, :PPOData2
alias_attribute :ppo_data_3, :PPOData3
alias_attribute :last_name, :LastName
alias_attribute :provider_line_12, :ProviderLine12
alias_attribute :claim_to_12, :ClaimTo12
def attributes
rails_like = {
id: self.id,
facility: self.facility,
employer_name: self.employer_name,
full_name: self.full_name,
ssn: self.ssn,
medical_coverage: self.medical_coverage,
medical_eff_date: self.medical_eff_date,
group_number: self.group_number,
dental_coverage: self.dental_coverage,
dental_eff_date: self.dental_eff_date,
dental_group_num: self.dental_group_num,
card_type: self.card_type,
provider_code: self.provider_code,
provider_line_1: self.provider_line_1,
provider_line_2: self.provider_line_2,
provider_line_3: self.provider_line_3,
provider_line_4: self.provider_line_4,
provider_line_5: self.provider_line_5,
provider_line_6: self.provider_line_6,
provider_line_7: self.provider_line_7,
provider_line_8: self.provider_line_8,
provider_line_9: self.provider_line_9,
provider_line_10: self.provider_line_10,
provider_line_11: self.provider_line_11,
mail_to: self.mail_to,
mail_to_2: self.mail_to_2,
claim_to_1: self.claim_to_1,
claim_to_2: self.claim_to_2,
claim_to_3: self.claim_to_3,
claim_to_4: self.claim_to_4,
claim_to_5: self.claim_to_5,
claim_to_6: self.claim_to_6,
claim_to_7: self.claim_to_7,
claim_to_8: self.claim_to_8,
claim_to_9: self.claim_to_9,
claim_to_10: self.claim_to_10,
claim_to_11: self.claim_to_11,
contact_line_1: self.contact_line_1,
contact_line_2: self.contact_line_2,
contact_line_3: self.contact_line_3,
group_number: self.group_number,
family_id: self.family_id,
group_no: self.group_no,
rx_group: self.rx_group,
help_desk: self.help_desk,
customer_service: self.customer_service,
web_url: self.web_url,
expr_1: self.expr_1,
line_3: self.line_3,
dependent_1: self.dependent_1,
dependent_2: self.dependent_2,
dependent_3: self.dependent_3,
dependent_4: self.dependent_4,
dependent_5: self.dependent_5,
dependent_6: self.dependent_6,
dependent_7: self.dependent_7,
dependent_8: self.dependent_8,
benefit_desc_1: self.benefit_desc_1,
benefit_1: self.benefit_1,
benefit_desc_2: self.benefit_desc_2,
benefit_2: self.benefit_2,
benefit_desc_3: self.benefit_desc_3,
benefit_3: self.benefit_3,
benefit_desc_4: self.benefit_desc_4,
benefit_4: self.benefit_4,
benefit_desc_5: self.benefit_desc_5,
benefit_5: self.benefit_5,
benefit_desc_6: self.benefit_desc_6,
benefit_6: self.benefit_6,
benefit_desc_7: self.benefit_desc_7,
benefit_7: self.benefit_7,
benefit_desc_8: self.benefit_desc_8,
benefit_8: self.benefit_8,
benefit_desc_9: self.benefit_desc_9,
benefit_9: self.benefit_9,
benefit_desc_10: self.benefit_desc_10,
benefit_10: self.benefit_10,
benefit_desc_11: self.benefit_desc_11,
benefit_11: self.benefit_11,
benefit_desc_12: self.benefit_desc_12,
benefit_12: self.benefit_12,
benefit_desc_13: self.benefit_desc_13,
benefit_13: self.benefit_13,
benefit_desc_14: self.benefit_desc_14,
benefit_14: self.benefit_14,
pl_plan_key: self.pl_plan_key,
primary_mb_member_key: self.primary_mb_member_key,
ppo_lookup_1: self.ppo_lookup_1,
ppo_lookup_2: self.ppo_lookup_2,
precert_1: self.precert_1,
precert_2: self.precert_2,
precert_3: self.precert_3,
precert_4: self.precert_4,
precert_5: self.precert_5,
precert_6: self.precert_6,
misc_data: self.misc_data,
ppo_data: self.ppo_data,
ppo_data_2: self.ppo_data_2,
ppo_data_3: self.ppo_data_3,
last_name: self.last_name,
provider_line_12: self.provider_line_12,
claim_to_12: self.claim_to_12,
}
super.merge(rails_like)
end
end
end
+1 -1
View File
@@ -1,5 +1,5 @@
module Vhcs
class HLIDCardsEgg < VhcsRecord
class HlidCardsEgg < VhcsRecord
self.table_name = 'HLIDCardsEgg'
+217
View File
@@ -0,0 +1,217 @@
module Vhcs
class HlidCardsViewEgg < VhcsRecord
self.table_name = 'HLIDCardsViewEgg'
alias_attribute :facility, :Facility
alias_attribute :division, :Division
alias_attribute :full_name, :FullName
alias_attribute :ssn, :SSN
alias_attribute :medical_coverage, :MedicalCoverage
alias_attribute :medical_eff_date, :MedicalEffDate
alias_attribute :medical_group_num, :MedicalGroupNum
alias_attribute :dental_coverage, :DentalCoverage
alias_attribute :dental_eff_date, :DentalEffDate
alias_attribute :dental_group_num, :DentalGroupNum
alias_attribute :card_type, :CardType
alias_attribute :provider_code, :ProviderCode
alias_attribute :provider_line_1, :ProviderLine1
alias_attribute :provider_line_2, :ProviderLine2
alias_attribute :provider_line_3, :ProviderLine3
alias_attribute :provider_line_4, :ProviderLine4
alias_attribute :provider_line_5, :ProviderLine5
alias_attribute :provider_line_6, :ProviderLine6
alias_attribute :provider_line_7, :ProviderLine7
alias_attribute :provider_line_8, :ProviderLine8
alias_attribute :provider_line_9, :ProviderLine9
alias_attribute :provider_line_1_0, :ProviderLine10
alias_attribute :provider_line_1_1, :ProviderLine11
alias_attribute :mail_to, :MailTo
alias_attribute :mail_to_2, :MailTo2
alias_attribute :claim_to_1, :ClaimTo1
alias_attribute :claim_to_2, :ClaimTo2
alias_attribute :claim_to_3, :ClaimTo3
alias_attribute :claim_to_4, :ClaimTo4
alias_attribute :claim_to_5, :ClaimTo5
alias_attribute :claim_to_6, :ClaimTo6
alias_attribute :claim_to_7, :ClaimTo7
alias_attribute :claim_to_8, :ClaimTo8
alias_attribute :claim_to_9, :ClaimTo9
alias_attribute :claim_to_1_0, :ClaimTo10
alias_attribute :claim_to_1_1, :ClaimTo11
alias_attribute :contact_line_1, :ContactLine1
alias_attribute :contact_line_2, :ContactLine2
alias_attribute :contact_line_3, :ContactLine3
alias_attribute :group_number, :GroupNumber
alias_attribute :family_id, :FamilyId
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 :expr_1, :Expr1
alias_attribute :line_3, :Line3
alias_attribute :dependent_1, :Dependent1
alias_attribute :dependent_2, :Dependent2
alias_attribute :dependent_3, :Dependent3
alias_attribute :dependent_4, :Dependent4
alias_attribute :dependent_5, :Dependent5
alias_attribute :dependent_6, :Dependent6
alias_attribute :dependent_7, :Dependent7
alias_attribute :dependent_8, :Dependent8
alias_attribute :ben_desc_1, :BenDesc1
alias_attribute :ben_1, :Ben1
alias_attribute :ben_desc_2, :BenDesc2
alias_attribute :ben_2, :Ben2
alias_attribute :ben_desc_3, :BenDesc3
alias_attribute :ben_3, :Ben3
alias_attribute :ben_desc_4, :BenDesc4
alias_attribute :ben_4, :Ben4
alias_attribute :ben_desc_5, :BenDesc5
alias_attribute :ben_5, :Ben5
alias_attribute :ben_desc_6, :BenDesc6
alias_attribute :ben_6, :Ben6
alias_attribute :ben_desc_7, :BenDesc7
alias_attribute :ben_7, :Ben7
alias_attribute :ben_desc_8, :BenDesc8
alias_attribute :ben_8, :Ben8
alias_attribute :ben_desc_9, :BenDesc9
alias_attribute :ben_9, :Ben9
alias_attribute :ben_desc_1_0, :BenDesc10
alias_attribute :ben_1_0, :Ben10
alias_attribute :ben_desc_1_1, :BenDesc11
alias_attribute :ben_1_1, :Ben11
alias_attribute :ben_desc_1_2, :BenDesc12
alias_attribute :ben_1_2, :Ben12
alias_attribute :ben_desc_1_3, :BenDesc13
alias_attribute :ben_1_3, :Ben13
alias_attribute :ben_desc_1_4, :BenDesc14
alias_attribute :ben_1_4, :Ben14
alias_attribute :pl_plan_key, :PLPlanKey
alias_attribute :mb_member_key, :MBMemberKey
alias_attribute :provider_lookup_1, :ProviderLookup1
alias_attribute :provider_lookup_2, :ProviderLookup2
alias_attribute :precert_1, :Precert1
alias_attribute :precert_2, :Precert2
alias_attribute :precert_3, :Precert3
alias_attribute :precert_4, :Precert4
alias_attribute :precert_5, :Precert5
alias_attribute :precert_6, :Precert6
alias_attribute :miscdata, :MISCDATA
alias_attribute :ppodata, :PPODATA
alias_attribute :ppodata_2, :PPODATA2
alias_attribute :ppodata_3, :PPODATA3
alias_attribute :last_name, :LastName
alias_attribute :provider_line_1_2, :ProviderLine12
alias_attribute :claim_to_1_2, :ClaimTo12
def attributes
rails_like = {
facility: self.facility,
division: self.division,
full_name: self.full_name,
ssn: self.ssn,
medical_coverage: self.medical_coverage,
medical_eff_date: self.medical_eff_date,
medical_group_num: self.medical_group_num,
dental_coverage: self.dental_coverage,
dental_eff_date: self.dental_eff_date,
dental_group_num: self.dental_group_num,
card_type: self.card_type,
provider_code: self.provider_code,
provider_line_1: self.provider_line_1,
provider_line_2: self.provider_line_2,
provider_line_3: self.provider_line_3,
provider_line_4: self.provider_line_4,
provider_line_5: self.provider_line_5,
provider_line_6: self.provider_line_6,
provider_line_7: self.provider_line_7,
provider_line_8: self.provider_line_8,
provider_line_9: self.provider_line_9,
provider_line_1_0: self.provider_line_1_0,
provider_line_1_1: self.provider_line_1_1,
mail_to: self.mail_to,
mail_to_2: self.mail_to_2,
claim_to_1: self.claim_to_1,
claim_to_2: self.claim_to_2,
claim_to_3: self.claim_to_3,
claim_to_4: self.claim_to_4,
claim_to_5: self.claim_to_5,
claim_to_6: self.claim_to_6,
claim_to_7: self.claim_to_7,
claim_to_8: self.claim_to_8,
claim_to_9: self.claim_to_9,
claim_to_1_0: self.claim_to_1_0,
claim_to_1_1: self.claim_to_1_1,
contact_line_1: self.contact_line_1,
contact_line_2: self.contact_line_2,
contact_line_3: self.contact_line_3,
group_number: self.group_number,
family_id: self.family_id,
group_no: self.group_no,
rx_group_id: self.rx_group_id,
help_desk: self.help_desk,
customer_service: self.customer_service,
web_url: self.web_url,
expr_1: self.expr_1,
line_3: self.line_3,
dependent_1: self.dependent_1,
dependent_2: self.dependent_2,
dependent_3: self.dependent_3,
dependent_4: self.dependent_4,
dependent_5: self.dependent_5,
dependent_6: self.dependent_6,
dependent_7: self.dependent_7,
dependent_8: self.dependent_8,
ben_desc_1: self.ben_desc_1,
ben_1: self.ben_1,
ben_desc_2: self.ben_desc_2,
ben_2: self.ben_2,
ben_desc_3: self.ben_desc_3,
ben_3: self.ben_3,
ben_desc_4: self.ben_desc_4,
ben_4: self.ben_4,
ben_desc_5: self.ben_desc_5,
ben_5: self.ben_5,
ben_desc_6: self.ben_desc_6,
ben_6: self.ben_6,
ben_desc_7: self.ben_desc_7,
ben_7: self.ben_7,
ben_desc_8: self.ben_desc_8,
ben_8: self.ben_8,
ben_desc_9: self.ben_desc_9,
ben_9: self.ben_9,
ben_desc_1_0: self.ben_desc_1_0,
ben_1_0: self.ben_1_0,
ben_desc_1_1: self.ben_desc_1_1,
ben_1_1: self.ben_1_1,
ben_desc_1_2: self.ben_desc_1_2,
ben_1_2: self.ben_1_2,
ben_desc_1_3: self.ben_desc_1_3,
ben_1_3: self.ben_1_3,
ben_desc_1_4: self.ben_desc_1_4,
ben_1_4: self.ben_1_4,
pl_plan_key: self.pl_plan_key,
mb_member_key: self.mb_member_key,
provider_lookup_1: self.provider_lookup_1,
provider_lookup_2: self.provider_lookup_2,
precert_1: self.precert_1,
precert_2: self.precert_2,
precert_3: self.precert_3,
precert_4: self.precert_4,
precert_5: self.precert_5,
precert_6: self.precert_6,
miscdata: self.miscdata,
ppodata: self.ppodata,
ppodata_2: self.ppodata_2,
ppodata_3: self.ppodata_3,
last_name: self.last_name,
provider_line_1_2: self.provider_line_1_2,
claim_to_1_2: self.claim_to_1_2,
}
super.merge(rails_like)
end
end
end
+47
View File
@@ -0,0 +1,47 @@
module Vhcs
class PbEntityAddress < VhcsRecord
self.table_name = 'PBEntityAddress'
alias_attribute :pb_entity_address_key, :PBEntityAddressKey
alias_attribute :pb_entity_key, :PBEntityKey
alias_attribute :address_type_id, :AddressTypeID
alias_attribute :street_line_1, :StreetLine1
alias_attribute :street_line_2, :StreetLine2
alias_attribute :city, :City
alias_attribute :state, :State
alias_attribute :zip, :Zip
alias_attribute :country_code, :CountryCode
alias_attribute :county, :County
alias_attribute :override_pb_entity_address_key, :OverridePBEntityAddressKey
alias_attribute :when_last_changed, :WhenLastChanged
alias_attribute :who_last_changed, :WhoLastChanged
alias_attribute :full_address_to_use, :FullAddressToUse
alias_attribute :country_sub_div, :CountrySubDiv
alias_attribute :full_address, :FullAddress
def attributes
rails_like = {
pb_entity_address_key: self.pb_entity_address_key,
pb_entity_key: self.pb_entity_key,
address_type_id: self.address_type_id,
street_line_1: self.street_line_1,
street_line_2: self.street_line_2,
city: self.city,
state: self.state,
zip: self.zip,
country_code: self.country_code,
county: self.county,
override_pb_entity_address_key: self.override_pb_entity_address_key,
when_last_changed: self.when_last_changed,
who_last_changed: self.who_last_changed,
full_address_to_use: self.full_address_to_use,
country_sub_div: self.country_sub_div,
full_address: self.full_address,
}
super.merge(rails_like)
end
end
end
+43
View File
@@ -0,0 +1,43 @@
module Vhcs
class PbOrgUnit < VhcsRecord
self.table_name = 'PBOrgUnit'
alias_attribute :pb_entity_key, :PBEntityKey
alias_attribute :web_site, :WebSite
alias_attribute :federal_tax_id, :FederalTaxID
alias_attribute :duns_number, :DunsNumber
alias_attribute :company_number, :CompanyNumber
alias_attribute :company_location, :CompanyLocation
alias_attribute :division, :Division
alias_attribute :policy_number, :PolicyNumber
alias_attribute :when_last_changed, :WhenLastChanged
alias_attribute :who_last_changed, :WhoLastChanged
alias_attribute :mmsea_employer_size_g_1_1_5, :MMSEAEmployerSize_G115
alias_attribute :wait_period_delay_type_g_1_0_7, :WaitPeriodDelayType_G107
alias_attribute :wait_period, :WaitPeriod
alias_attribute :wait_period_unit_g_1_0_6, :WaitPeriodUnit_G106
def attributes
rails_like = {
pb_entity_key: self.pb_entity_key,
web_site: self.web_site,
federal_tax_id: self.federal_tax_id,
duns_number: self.duns_number,
company_number: self.company_number,
company_location: self.company_location,
division: self.division,
policy_number: self.policy_number,
when_last_changed: self.when_last_changed,
who_last_changed: self.who_last_changed,
mmsea_employer_size_g_1_1_5: self.mmsea_employer_size_g_1_1_5,
wait_period_delay_type_g_1_0_7: self.wait_period_delay_type_g_1_0_7,
wait_period: self.wait_period,
wait_period_unit_g_1_0_6: self.wait_period_unit_g_1_0_6,
}
super.merge(rails_like)
end
end
end
+23
View File
@@ -0,0 +1,23 @@
module Vhcs
class PlPlanGroupCode < VhcsRecord
self.table_name = 'PLPlanGroupCode'
alias_attribute :group_code, :GroupCode
alias_attribute :pl_plan_key, :PLPlanKey
alias_attribute :pl_cov_type_hdr_key, :PLCovTypeHdrKey
alias_attribute :group_code_desc, :GroupCodeDesc
def attributes
rails_like = {
group_code: self.group_code,
pl_plan_key: self.pl_plan_key,
pl_cov_type_hdr_key: self.pl_cov_type_hdr_key,
group_code_desc: self.group_code_desc,
}
super.merge(rails_like)
end
end
end
+14
View File
@@ -0,0 +1,14 @@
class CallStoredProc
def initialize(procedure_name, args = {})
@procedure_name = procedure_name
@args = args
end
def call
params_sql = @args.map { |key, value| "@#{key} = :#{key}" }.join(', ')
sql_template = "EXEC #{@procedure_name} #{params_sql}"
sanitized_sql = VhcsRecord.send(:sanitize_sql_array, [sql_template, @args])
VhcsRecord.connection.exec_query(sanitized_sql)
end
end
@@ -0,0 +1,94 @@
class GetAllIDCardDataByPlanTPAQuery
def initialize(pl_plan_key)
@pl_plan_key = ActiveRecord::Base.connection.quote(pl_plan_key)
end
def call
VhcsRecord.connection.exec_query(sql).rows
end
def to_id_cards_data
raw_data = call
all_id_cards_data = []
raw_data.each do |rd|
id_card_data = {
id: rd[0],
mb_member_key: rd[1],
mbr_type: rd[2],
division: rd[3],
full_name: rd[7],
family_id: rd[8],
mbr_class: rd[9],
effect_date: rd[11],
state: rd[12],
pl_plan_key: rd[14],
group_number: rd[15],
medical_group_num: rd[16],
dental_group_num: rd[17],
pb_product_key: rd[18],
mb_member_key: rd[19]
}
all_id_cards_data.push(id_card_data)
end
all_id_cards_data
end
private
def sql
<<~SQL
SELECT DISTINCT ROW_NUMBER() OVER(ORDER BY pbm.FamilyId ASC) as Id, pbc.MBMemberKey,
CASE WHEN div.PBENtityKey = 344215 OR div.PBENtityKey = 344217 THEN 'OSB' ELSE ou.CompanyNumber END as MbrType,
substring(div.LastName,0,41) as Div ,
substring(pbe.FirstName,0,25) as MbrFirst,
substring(pbe.MiddleName,0,25) as MbrMiddle,
substring(pbe.LastName,0,50) as MbrLast,
(substring(pbe.FirstName, 0, 25) + ' ' + substring(pbe.LastName, 0, 50)) as FullName,
pbm.FamilyId,
UPPER(lct.shortdesc) as MbrClass,
2 as MedOrDent,pp.InEffect as EffectDate,
pbea.State,ISNULL(oua.State,pbea.State) as EmpState,
M.PLPlanKey,
PC.GroupNumber,
PC.MedicalNumber,
PC.DentalNumber,
P.PBProductKey,
m.PBEntityKey as PrimaryMBMemberKey
FROM VWMBMember M INNER JOIN PBEntityClaimsData pbc on pbc.MBMemberKey=M.MBMemberKey
LEFT OUTER Join HLPlanCode PC ON PC.PlanKey = M.PLPlanKey
INNER JOIN PBMember pbm on pbm.PBEntityKey=pbc.PBEntityKey and pbm.EnrolleeTypeKey=1044
INNER JOIN PBEntity pbe on pbe.PBEntityKey=pbm.PBEntityKey
INNER JOIN PBEntityAddress pbea on pbea.PBEntityKey=pbe.PBEntityKey and pbea.AddressTypeID=1137
INNER JOIN PBCoveredEntities ce on ce.PBEntityKey=pbe.PBEntityKey
INNER JOIN PBProductParticipation pp on pp.PBProductParticipationKey=ce.PBProductParticipationKey
INNER JOIN (SELECT ce1.PBEntityKey, pp1.PBProductAvailabilityKey, MAX(pp1.WhenLastChanged) as WhenLastChanged,
pp1.CoverageTypeCode
FROM PBCoveredEntities ce1
INNER JOIN PBProductParticipation pp1 on pp1.PBProductParticipationKey = ce1.PBProductParticipationKey
GROUP BY ce1.PBEntityKey, pp1.PBProductAvailabilityKey,pp1.CoverageTypeCode)
cepp ON cepp.PBEntityKey = ce.PBEntityKey AND cepp.PBProductAvailabilityKey = pp.PBProductAvailabilityKey
and cepp.CoverageTypeCode = pp.CoverageTypeCode
INNER JOIN GEN_LookupTables lct ON lct.RecordID = pp.CoverageTypeCode
INNER JOIN PBProductAvailability pa on pa.PBProductAvailabilityKey=pp.PBProductAvailabilityKey
INNER JOIN PBProduct p on p.PBProductKey=pa.PBProductKey
INNER JOIN PBAffiliation aff ON aff.PBAffiliationKey = pp.PBAffiliationKey
INNER JOIN PBEntity div on div.PBEntityKey=aff.ParentPBEntityKey
LEFT OUTER JOIN PBOrgUnit ou on ou.PBEntityKey=div.PBEntityKey
LEFT OUTER JOIN PBEntityAddress oua on oua.PBEntityKey=ou.PBEntityKey and oua.AddressTypeID=1137 WHERE p.PBProductKey in (Select DISTINCT PBProductKey From PBProduct Where FullDescription NOT LIKE '%LIFE%' AND FullDescription NOT LIKE '%VIS%')
AND pp.InEffect <= getdate() +90
AND (pp.OutOfEffect-1 > getdate() AND
pp.OutOfEffect>pp.InEffect)
AND pp.OutOfEffect=(Select Max(Part.OutOfEffect) From PBProductParticipation Part
INNER JOIN PBProductAvailability Aval on Aval.PBProductAvailabilityKey=Part.PBProductAvailabilityKey
INNER JOIN PBProduct Prod on Prod.PBProductKey=Aval.PBProductKey
Where Prod.PBProductKey = p.PBProductKey
AND Part.PBProductParticipationKey = pp.PBProductParticipationKey)
AND M.EnrolleeTypeKey = '1044'
AND M.PLPlanKey = #{@pl_plan_key}
SQL
end
end
+95
View File
@@ -0,0 +1,95 @@
class GetIdCardDataTpaQuery
def initialize(family_id)
@family_id = ActiveRecord::Base.connection.quote(family_id)
if family_id.length == 9
@entity_type = ActiveRecord::Base.connection.quote("FamilyId")
else
@entity_type = ActiveRecord::Base.connection.quote("PBEntityKey")
end
end
def call
VhcsRecord.connection.exec_query(sql).rows.first
end
def to_id_card_data
raw_data = call
id_card_data = {
id: raw_data[0],
mb_member_key: raw_data[1],
mbr_type: raw_data[2],
division: raw_data[3],
full_name: raw_data[7],
family_id: raw_data[8],
mbr_class: raw_data[9],
effect_date: raw_data[11],
state: raw_data[12],
pl_plan_key: raw_data[14],
group_number: raw_data[15],
medical_group_num: raw_data[16],
dental_group_num: raw_data[17],
pb_product_key: raw_data[18],
mb_member_key: raw_data[19]
}
[id_card_data]
end
private
def sql
<<~SQL
SELECT DISTINCT ROW_NUMBER() OVER(ORDER BY pbm.FamilyId ASC) as Id, pbc.MBMemberKey,
isnull(ou.CompanyNumber,'') as MbrType,
CASE WHEN m.PLPlanKey = '14' THEN 'DUPLIN COUNTY GOVERNMENT' ELSE substring(div.LastName,0,41) END as Div,
substring(pbe.FirstName,0,25) as MbrFirst,
substring(pbe.MiddleName,0,25) as MbrMiddle,
substring(pbe.LastName,0,50) as MbrLast,
(substring(pbe.FirstName, 0, 25) + ' ' + substring(pbe.LastName, 0, 50)) as FullName,
pbm.FamilyId,
UPPER(lct.shortdesc) as MbrClass,
2 as MedOrDent,
pp.InEffect as EffectDate,
pbea.State,ISNULL(oua.State,pbea.State) as EmpState,
M.PLPlanKey,
PC.GroupNumber,
PC.MedicalNumber,
PC.DentalNumber,
P.PBProductKey,
m.PBEntityKey as PrimaryMBMemberKey
FROM VWMBMember M
INNER JOIN PBEntityClaimsData pbc on pbc.MBMemberKey=M.MBMemberKey
Inner Join HLPlanCode PC ON PC.PlanKey = M.PLPlanKey
INNER JOIN PBMember pbm on pbm.PBEntityKey=pbc.PBEntityKey and pbm.EnrolleeTypeKey=1044
INNER JOIN PBEntity pbe on pbe.PBEntityKey=pbm.PBEntityKey
INNER JOIN PBEntityAddress pbea on pbea.PBEntityKey=pbe.PBEntityKey and pbea.AddressTypeID=1137
INNER JOIN PBCoveredEntities ce on ce.PBEntityKey=pbe.PBEntityKey
INNER JOIN PBProductParticipation pp on pp.PBProductParticipationKey=ce.PBProductParticipationKey
INNER JOIN (SELECT ce1.PBEntityKey, pp1.PBProductAvailabilityKey, MAX(pp1.WhenLastChanged) as WhenLastChanged,
pp1.CoverageTypeCode
FROM PBCoveredEntities ce1
INNER JOIN PBProductParticipation pp1 on pp1.PBProductParticipationKey = ce1.PBProductParticipationKey
GROUP BY ce1.PBEntityKey, pp1.PBProductAvailabilityKey,pp1.CoverageTypeCode)
cepp ON cepp.PBEntityKey = ce.PBEntityKey AND cepp.PBProductAvailabilityKey = pp.PBProductAvailabilityKey
and cepp.CoverageTypeCode = pp.CoverageTypeCode
INNER JOIN GEN_LookupTables lct ON lct.RecordID = pp.CoverageTypeCode
INNER JOIN PBProductAvailability pa on pa.PBProductAvailabilityKey=pp.PBProductAvailabilityKey
INNER JOIN PBProduct p on p.PBProductKey=pa.PBProductKey
INNER JOIN PBAffiliation aff ON aff.PBAffiliationKey = pp.PBAffiliationKey
INNER JOIN PBEntity div on div.PBEntityKey=aff.ParentPBEntityKey
LEFT OUTER JOIN PBOrgUnit ou on ou.PBEntityKey=div.PBEntityKey
LEFT OUTER JOIN PBEntityAddress oua on oua.PBEntityKey=ou.PBEntityKey and oua.AddressTypeID=1137
WHERE p.PBProductKey in (Select PBProductKey From PBProduct Where FullDescription NOT LIKE '%LIFE%' AND FullDescription NOT LIKE '%VISION%' AND FullDescription NOT LIKE '%DENT%')
AND pp.InEffect <= getdate() +90
AND (pp.OutOfEffect-1 > getdate() AND pp.OutOfEffect>pp.InEffect)
AND pp.OutOfEffect=(Select Max(Part.OutOfEffect) From PBProductParticipation Part
INNER JOIN PBProductAvailability Aval on Aval.PBProductAvailabilityKey=Part.PBProductAvailabilityKey
INNER JOIN PBProduct Prod on Prod.PBProductKey=Aval.PBProductKey
Where Prod.PBProductKey = p.PBProductKey
AND Part.PBProductParticipationKey = pp.PBProductParticipationKey)
AND pbm.#{@entity_type}=#{@family_id}
AND M.EnrolleeTypeKey='1044'
SQL
end
end
View File
@@ -0,0 +1,30 @@
module AutomationService
class BatchEmployerUpdate
def initialize(pl_plan_keys = nil)
@pl_plan_keys = pl_plan_keys
end
def call
sql_query = "SELECT PLPlanKey, PlanId, ShortDesc FROM PLPlanHeader
WHERE ActiveInactive = 'Active'"
if @pl_plan_keys.present?
sql_query = sql_query.concat(" AND PLPlanKey IN (#{@pl_plan_keys.join(',')})")
end
employer_plan_headers = VhcsRecord.connection.select_all(sql_query)
employer_update_futures = employer_plan_headers.map do |employer_plan_header|
Concurrent::Future.execute do
ActiveRecord::Base.connection_pool.with_connection do
UpdateEmployerJob.perform_later(employer_plan_header: employer_plan_header)
end
end
end
employer_update_futures.map(&:value)
end
end
end
# AutomationService::MemberUpdate('13', 337710)
@@ -0,0 +1,38 @@
module AutomationService
class EmployerMembersUpdate
def initialize(pl_plan_key)
@pl_plan_key = pl_plan_key
end
def call
employer = Employer.includes(:id_card_setup).find_by(pl_plan_key: @pl_plan_key)
card_setup = employer.id_card_setup
puts "-- #{employer.name}"
# employer_members =[]
vw_mb_members = Vhcs::VwmbMember.where(enrollee_type_value_id: 1, pl_plan_key: @pl_plan_key).select(:mb_member_key, :pb_entity_key, :pl_plan_key, :family_id, :full_name_last_name_first, :social_security_number)
# vw_mb_members.each do |vw_mb_member|
# member = UpdateMemberJob.perform_now(@pb_entity_key, employer.id, card_setup.has_divisions, card_setup.has_dental, true, vw_mb_member)
# end
# employer.members = employer_members
# employer.save
member_update_futures = vw_mb_members.map do |vw_mb_member|
Concurrent::Future.execute do
ActiveRecord::Base.connection_pool.with_connection do
UpdateMemberJob.perform_now(vw_mb_member.pb_entity_key, employer.id, card_setup.has_divisions, card_setup.has_dental, vw_mb_member)
end
end
end
member_updates = member_update_futures.map(&:value).compact
employer.members = member_updates
if member_updates.empty? && employer.id_card_setup.active
employer.active = false
end
employer.save
end
end
end
@@ -0,0 +1,22 @@
module AutomationService
class EmployerPlansUpdate
def initialize(pl_plan_key)
@pl_plan_key = pl_plan_key
end
def call
# employer = Employer.includes(:id_card_setup).find_by(pl_plan_key: @pl_plan_key)
# card_setup = employer.id_card_setup
UpdateEmployerPlansJob.new.perform(@pl_plan_key)
# if employer.present?
# employer.save
# else
# Member.find_by(pb_entity_key: vw_mb_member[:pb_entity_key]).destroy
# end
end
end
end
# AutomationService::MemberUpdate('13', 337710)
@@ -0,0 +1,23 @@
module AutomationService
class EmployerUpdate
def initialize(employer_identifier, full_sync = false)
@employer_identifier = employer_identifier
@full_sync = full_sync
end
def call
# employer = Employer.includes(:id_card_setup).find_by(employer_identifier: @employer_identifier)
# card_setup = employer.id_card_setup
UpdateEmployerJob.new.perform(employer_identifier: @employer_identifier, full_sync: @full_sync)
# if employer.present?
# employer.save
# else
# Member.find_by(pb_entity_key: vw_mb_member[:pb_entity_key]).destroy
# end
end
end
end
# AutomationService::MemberUpdate('13', 337710)
@@ -0,0 +1,23 @@
module AutomationService
class MemberUpdate
def initialize(pl_plan_key, pb_entity_key)
@pl_plan_key = pl_plan_key
@pb_entity_key = pb_entity_key
end
def call
employer = Employer.includes(:id_card_setup).find_by(pl_plan_key: @pl_plan_key)
card_setup = employer.id_card_setup
member = UpdateMemberJob.perform_now(@pb_entity_key, employer.id, card_setup.has_divisions, card_setup.has_dental)
if member.present?
member.save
else
Member.find_by(pb_entity_key: vw_mb_member[:pb_entity_key]).destroy
end
end
end
end
# AutomationService::MemberUpdate('13', 337710)
@@ -1,33 +0,0 @@
module BenefitsWordDoc
class MapNetworkInformation
def initialize(employer, word_doc_section)
@employer = employer
@word_doc_section = word_doc_section
end
def call
network_matches = []
@word_doc_section.each do |line|
if network_matches.exclude?("Cigna") && line.match?(/cigna/i)
network_matches.push("Cigna")
elsif network_matches.exclude?("Medcost") && line.match?(/medcost/i)
network_matches.push("Medcost")
end
end
if network_matches.length == 1
network_provider = network_matches.first
@employer.network_provider = network_provider
@employer.default_network_logo = "#{network_provider}Logo.png"
provider_code = network_provider == "Cigna" ? "5" : "2"
@employer.card_provider = CardProvider.find_by(provider_code: provider_code)
@employer.card_rx = CardRx.find_by(web_url: "www.FairosRx.com")
end
@employer
end
end
end
@@ -1,32 +0,0 @@
class BenefitsWordDocProcessor
def initialize(word_doc, employer=nil)
@word_doc = word_doc
if employer
@employer = employer
else
@employer = Employer.new
end
end
def call
doc = Docx::Document.open(@word_doc)
data_lines = doc.paragraphs.map { |p| p.to_s.squish }.reject!(&:empty?)
employer_information, plans_and_network = data_lines.split("Medical Plan")
plan_information, network_information = plans_and_network.split("Claims Submission")
# employer_information = data_lines.slice(0, start_of_plans_index)
# plan_information = data_lines.slice(start_of_plans_index + 1..)
# network_information = data_lines.slice(start_of_network_index + 1..)
@employer = BenefitsWordDoc::MapEmployerInformation.new(@employer, employer_information).call
@employer = BenefitsWordDoc::MapEmployerLogo.new(@employer, @word_doc).call
@employer = BenefitsWordDoc::MapPlansInformation.new(@employer, plan_information).call
@employer = BenefitsWordDoc::MapNetworkInformation.new(@employer, network_information).call
@employer
end
end
@@ -1,4 +1,4 @@
class BenefitsWordDocProcessorOld
class WordDocProcessorOld
def initialize(word_doc, process=nil)
@word_doc = word_doc
@@ -1,8 +1,9 @@
module BenefitsWordDoc
module BenefitsWordDocService
class MapEmployerInformation
def initialize(employer, word_doc_section)
@employer = employer
@card_setup = @employer.id_card_setup
@word_doc_section = word_doc_section
end
@@ -27,6 +28,9 @@ module BenefitsWordDoc
end
end
end
@card_setup.print_name = @employer.name
@employer.name = @employer.name.titleize
@card_setup.rx_group_number = @employer.group_number
@employer
end
@@ -1,8 +1,9 @@
module BenefitsWordDoc
module BenefitsWordDocService
class MapEmployerLogo
def initialize(employer, word_doc)
@employer = employer
@card_setup = @employer.id_card_setup
@word_doc = word_doc
end
@@ -19,10 +20,9 @@ module BenefitsWordDoc
filename = @employer.name_to_logo_filename(file_extension)
logo = CardLogoFile.find_or_create_by(filename: filename) do |clf|
logo = IdCard::EmployerLogo.find_or_create_by(filename: filename) do |clf|
clf.image_data = image_binary
clf.content_type = meme_type
clf.logo_type = "employer"
end
# new_logo = CardLogoFile.create!(
@@ -32,16 +32,16 @@ module BenefitsWordDoc
# logo_type: "employer"
# )
image_io = StringIO.new(image_binary)
width, height = FastImage.size(image_io)
image_ratio = width.to_f / height
if (0.8..1.2).cover?(image_ratio)
@employer.single_card_template = "FairosRxIDCard-Half"
else
@employer.single_card_template = "FairosRxIDCard"
end
# image_io = StringIO.new(image_binary)
# width, height = FastImage.size(image_io)
# image_ratio = width.to_f / height
# if (0.8..1.2).cover?(image_ratio)
# @employer.single_card_template = "FairosRxIDCard-Half"
# else
# @employer.single_card_template = "FairosRxIDCard"
# end
@employer.employer_logo_filename = logo.filename
@card_setup.employer_logo = logo
end
end
@employer
@@ -0,0 +1,44 @@
module BenefitsWordDocService
class MapNetworkInformation
def initialize(employer, word_doc_section)
@employer = employer
@card_setup = @employer.id_card_setup
@word_doc_section = word_doc_section
end
def call
# network = @word_doc_section.each do |line|
# if line.match?(/cigna/i)
# return "Cigna"
# elsif line.match?(/medcost/i)
# return "Medcost"
# end
# end
network = @word_doc_section.find do |line|
if line.match?(/cigna/i)
break "Cigna"
elsif line.match?(/medcost/i)
break "MedCost"
end
end
# yellow_fruit_names_filtered = @word_doc_section.filter_map do |line|
# item[:name] if item[:color] == 'yellow'
# end
if network
@card_setup.network_provider = network
logo_name = "#{network}Logo.png"
@card_setup.network_logo = IdCard::NetworkLogo.find_by(filename: logo_name)
@card_setup.provider_section = IdCard::ProviderSection.find_by(title: network)
@card_setup.rx_section = IdCard::RxSection.find_by(title: "FairosRx")
end
@employer
end
end
end
@@ -1,8 +1,9 @@
module BenefitsWordDoc
module BenefitsWordDocService
class MapPlansInformation
def initialize(employer, word_doc_section)
@employer = employer
@card_setup = @employer.id_card_setup
@word_doc_section = word_doc_section
end
@@ -11,17 +12,21 @@ module BenefitsWordDoc
plans_indexes = @word_doc_section.each_index.select { |index| @word_doc_section[index].match?(/\d*\.?\d+k/i) }
plans_indexes.each do |plan_index|
new_plan = @employer.build_plan_with_default_benefits(title: @word_doc_section[plan_index])
new_plan = @card_setup.plans.build(title: @word_doc_section[plan_index])
plan_lines = @word_doc_section.slice(plan_index + 1, 14)
plan_lines.each_with_index do |line, i|
field_mapping = mapping_array[i]
field_regex = field_mapping[:doc_to_employer_regex]
if line.match(field_regex)
field_value = line.match(field_regex)[0].strip
elsif line.match(default_benefit_regex(field_mapping[:employer_benefit_desc_field]))
field_value = line.match(default_benefit_regex(field_mapping[:employer_benefit_desc_field]))[0].strip
if line.match(/(?<=:).+/)
field_value = line.match(/(?<=:).+/)[0].strip
else
field_value = line
field_regex = field_mapping[:doc_to_employer_regex]
if line.match(field_regex)
field_value = line.match(field_regex)[0].strip
elsif line.match(default_benefit_regex(field_mapping[:employer_benefit_desc_field]))
field_value = line.match(default_benefit_regex(field_mapping[:employer_benefit_desc_field]))[0].strip
else
field_value = line
end
end
employer_benefit_desc_field = field_mapping[:employer_benefit_desc_field]
new_benefit = new_plan.plan_benefits[i]
@@ -0,0 +1,35 @@
module BenefitsWordDocService
class WordDocProcessor
def initialize(word_doc, employer=nil)
@word_doc = word_doc
if employer
@employer = employer
else
@employer = Employer.new
@employer.build_id_card_setup
end
end
def call
doc = Docx::Document.open(@word_doc)
data_lines = doc.paragraphs.map { |p| p.to_s.squish }.reject!(&:empty?)
employer_information, plans_and_network = data_lines.split("Medical Plan")
plan_information, network_information = plans_and_network.split("Claims Submission")
# employer_information = data_lines.slice(0, start_of_plans_index)
# plan_information = data_lines.slice(start_of_plans_index + 1..)
# network_information = data_lines.slice(start_of_network_index + 1..)
@employer = BenefitsWordDocService::MapEmployerInformation.new(@employer, employer_information).call
@employer = BenefitsWordDocService::MapEmployerLogo.new(@employer, @word_doc).call
@employer = BenefitsWordDocService::MapPlansInformation.new(@employer, plan_information).call
@employer = BenefitsWordDocService::MapNetworkInformation.new(@employer, network_information).call
@employer
end
end
end
@@ -6,7 +6,7 @@ module EmployerCards
end
def call
@members = @employer.members
@members = @employer.members.order(:name)
@employer_cards = []
init_cards_and_set_member_fields
@@ -19,6 +19,31 @@ module EmployerCards
private
def init_cards_and_set_common_fields
employer_attributes = {
employer_name: @employer.id_card_display_name,
group_number: @employer.group_number,
rx_group: @employer.rx_group_number
}
rx_attributes = @employer.card_rx.attributes.with_indifferent_access.slice(
:customer_service,
:web_url
)
provider_attributes = @employer.card_provider.attributes.with_indifferent_access.slice(
:provider_code, :provider_line_1, :provider_line_2, :provider_line_3, :provider_line_4, :provider_line_5, :provider_line_6,
:provider_line_7, :provider_line_8, :provider_line_9, :provider_line_10, :provider_line_11, :provider_line_12,
:claim_to_1, :claim_to_2, :claim_to_3, :claim_to_4, :claim_to_5, :claim_to_6,
:claim_to_7, :claim_to_8, :claim_to_9, :claim_to_10, :claim_to_11, :claim_to_12
)
selected_attributes = employer_attributes.merge(rx_attributes).merge(provider_attributes)
@employer_cards.each do |card|
card.assign_attributes(selected_attributes)
end
end
def set_common_fields
employer_attributes = {
employer_name: @employer.id_card_display_name,
@@ -32,7 +57,7 @@ module EmployerCards
)
provider_attributes = @employer.card_provider.attributes.with_indifferent_access.slice(
:provider_line_1, :provider_line_2, :provider_line_3, :provider_line_4, :provider_line_5, :provider_line_6,
:provider_code, :provider_line_1, :provider_line_2, :provider_line_3, :provider_line_4, :provider_line_5, :provider_line_6,
:provider_line_7, :provider_line_8, :provider_line_9, :provider_line_10, :provider_line_11, :provider_line_12,
:claim_to_1, :claim_to_2, :claim_to_3, :claim_to_4, :claim_to_5, :claim_to_6,
:claim_to_7, :claim_to_8, :claim_to_9, :claim_to_10, :claim_to_11, :claim_to_12
@@ -58,21 +83,29 @@ module EmployerCards
end
def init_cards_and_set_member_fields
@group_dependents = Vhcs::VwmbMember.where(pl_plan_key: @employer.pl_plan_key)
@members.each do |me|
effect_date = determine_eff_date(me)
if effect_date
member_card = SampleIdCard.new()
selected_attributes = {
member_attributes = {
full_name: me.id_card_display_name,
primary_mb_member_key: me.mb_member_key,
name: me.name,
primary_mb_member_key: me.pb_entity_key,
family_id: me.family_id,
plan_id: me.plan_id,
medical_eff_date: effect_date.strftime("%m/%d/%Y")
}
dependent_attributes = get_dependent_fields(me)
selected_attributes = member_attributes.merge(dependent_attributes)
member_card.assign_attributes(selected_attributes)
@employer_cards.push(member_card)
if dependent_attributes.present?
@employer_cards.push(member_card)
end
end
end
end
@@ -102,7 +135,7 @@ module EmployerCards
def determine_eff_date(member)
participation = Vhcs::PbProductParticipation.joins('INNER JOIN "PBCoveredEntities" ON "PBProductParticipation"."PBProductParticipationKey" = "PBCoveredEntities"."PBProductParticipationKey"').where('"PBCoveredEntities"."PBEntityKey" = ?', member.pb_entity_key).first
participation = Vhcs::PbProductParticipation.joins('INNER JOIN "PBCoveredEntities" ON "PBProductParticipation"."PBProductParticipationKey" = "PBCoveredEntities"."PBProductParticipationKey"').where('"PBCoveredEntities"."PBEntityKey" = ?', member.pb_entity_key).last
in_effect = participation.in_effect
out_of_effect = participation.out_of_effect
@@ -114,8 +147,14 @@ module EmployerCards
end
def set_dependent_fields
# Not needed for sample card
def get_dependent_fields(member)
dependent_attributes = {}
dependents = @group_dependents.where(family_id: member.family_id).where.not(pb_entity_key: member.pb_entity_key)
dependents.each do |dep|
dependent_name = dep.first_name + ' ' + dep.last_name
dependent_attributes["dependent_#{dep.sequence_number - 1}".to_sym] = dependent_name
end
dependent_attributes
end
end
end
@@ -1,17 +1,15 @@
module EmployerCards
class JasperUrlGenerator
def initialize(employer, family_id)
def initialize(pl_plan_key, family_id, layout)
@pl_plan_key = pl_plan_key
@family_id = family_id
@employer = employer
@layout = layout
@card_setup = IdCard::Setup.find_by(pl_plan_key: pl_plan_key)
end
def call
# @net_logo = determine_network_logo
card_front_url = URI::HTTP.build(url_components("Front"))
card_back_url = URI::HTTP.build(url_components("Back"))
[card_front_url, card_back_url]
URI::HTTP.build(url_components)
end
private
@@ -30,17 +28,12 @@ module EmployerCards
end
# http://localhost:8080/trunk/PdfServlet?reportConn=BrittonConnect&id=&reportName=FairosRxSampleIDCard-Half&family_id=Classic%202K&employer_logo=BryanPestControl.jpeg&network_logo=CignaLogo.png&reportDir=secure/Documents&SUBREPORT_DIR=/&ImageDir=secure/Documents&netToken=3a4a8b03f4dfb0e6e3fc82dd369f70ef&FileType=PDF
# http://localhost:8080/trunk/PdfServlet?reportConn=BrittonConnect&id=&reportName=FairosRxSampleIDCard-Half&family_id=Classic%202K&employer_logo=BryanPestControl.jpeg&network_logo=CignaLogo.png&reportDir=secure/Documents&SUBREPORT_DIR=/&ImageDir=secure/Documents&netToken=3a4a8b03f4dfb0e6e3fc82dd369f70ef&FileType=PDF
def url_components(card_side)
if card_side == "Back" && @employer.single_card_template.include?("-Half")
template = @employer.single_card_template.gsub("-Half", "")
else
template = @employer.single_card_template
end
def url_components
{
host: '10.41.1.115',
port: 8080,
path: '/trunk/PdfServlet',
query: "reportConn=BrittonConnect&id=&reportName=#{template}-#{card_side}-Print&family_id=#{@family_id}&employer_logo=#{@employer.employer_logo_filename}&network_logo=#{determine_network_logo}&reportDir=secure/Documents&SUBREPORT_DIR=/&ImageDir=secure/Documents&netToken=3a4a8b03f4dfb0e6e3fc82dd369f70ef&FileType=PDF"
path: '/trunk/IdCardsServlet',
query: "reportConn=BrittonConnect&cardTemplate=#{@employer.single_card_template}&printType=#{@layout}&family_id=#{@family_id }&employer_logo=#{@employer.employer_logo_filename}&network_logo=#{determine_network_logo}&FileType=PDF"
}
end
+34 -9
View File
@@ -1,22 +1,47 @@
class EmployerCardsGenerator
def initialize(employer)
def initialize(employer, layout)
@employer = employer
@layout = layout
end
def call
SampleIdCard.where(employer_name: @employer.id_card_display_name).destroy_all
EmployerCards::DataFormatter.new(@employer).call
group_cards_pdf = CombinePDF.new
SampleIdCard.where(employer_name: @employer.id_card_display_name).each do |card|
urls = EmployerCards::JasperUrlGenerator.new(@employer, card.family_id).call
puts urls
card_front_pdf = SampleCard::JasperPdfGenerator.new(urls.first).call
card_back_pdf = SampleCard::JasperPdfGenerator.new(urls.last).call
if @layout == "FullPageCard"
group_cards_pdf_array = []
reprint = Vhcs::HlidCardEggData.where(group_number: @employer.group_number).pluck(:family_id)
SampleIdCard.where(employer_name: @employer.id_card_display_name).each do |card|
if reprint.include?(card.family_id)
url = EmployerCards::JasperUrlGenerator.new(@employer, card.family_id, @layout).call
puts url
card_pdf = SampleCard::JasperPdfGenerator.new(url).call
card_filename = "#{card.name.gsub(", ","_")}_digital_card_#{Date.today}.pdf"
# group_cards_pdf_array.add(card_filename, pdf_object.to_pdf)
group_cards_pdf_array << { name: card_filename, data: card_pdf.to_pdf }
end
end
group_cards_pdf << card_front_pdf
group_cards_pdf << card_back_pdf
# Initialize a string-based IO object
group_cards_pdf = Zip::OutputStream.write_buffer do |zio|
group_cards_pdf_array.each do |file|
zio.put_next_entry(file[:name])
zio.write(file[:data])
end
end
else
group_cards_pdf = CombinePDF.new
reprint = Vhcs::HlidCardEggData.where(group_number: @employer.group_number).pluck(:family_id)
SampleIdCard.where(employer_name: @employer.id_card_display_name).each do |card|
if reprint.include?(card.family_id)
url = EmployerCards::JasperUrlGenerator.new(@employer, card.family_id, @layout).call
puts url
card_pdf = SampleCard::JasperPdfGenerator.new(url).call
group_cards_pdf << card_pdf
end
end
end
# todays_date = DateTime.current.strftime('%Y%m%d%H%M%S')
@@ -0,0 +1,185 @@
module IdCardPrinterService
class CardDataFormatter
def initialize(employers_member_keys)
# @employer = employer
@employers_member_keys = Array.wrap(employers_member_keys)
# @employer = Employer.includes(id_card_setup: [:provider_section, :rx_section]).find_by(pl_plan_key: pl_plan_key)
# @card_setup = @employer.id_card_setup
end
def call
# blank_card = IdCard::PrintData.new()
# @employer_cards = []
print_card_futures = []
@employers_member_keys.each do |emk|
pl_plan_key = emk[:pl_plan_key]
@member_keys = emk[:member_keys]
@employer = Employer.includes(id_card_setup: [:provider_section, :rx_section]).find_by(pl_plan_key: pl_plan_key)
@card_setup = @employer.id_card_setup
base_card = initialize_employer_base_card()
create_plan_base_cards(base_card)
employer_card_futures = create_member_cards_async()
print_card_futures << employer_card_futures
end
print_card_futures.flatten.map(&:value)
end
private
def initialize_employer_base_card
employer_attributes = {
pl_plan_key: @employer.pl_plan_key,
group_number: @employer.group_number,
rx_group: @card_setup.rx_group_number,
network_provider: @card_setup.network_provider,
network_logo_filename: @card_setup.network_logo.filename,
employer_logo_filename: @card_setup.employer_logo.filename
}
unless @card_setup.has_divisions
employer_attributes.merge!({employer_name: @card_setup.print_name})
end
rx_attributes = @card_setup.rx_section.attributes.with_indifferent_access.slice(
:customer_service,
:web_url
)
provider_attributes = @card_setup.provider_section.attributes.with_indifferent_access.slice(
:provider_line_1, :provider_line_2, :provider_line_3, :provider_line_4, :provider_line_5, :provider_line_6,
:provider_line_7, :provider_line_8, :provider_line_9, :provider_line_10, :provider_line_11, :provider_line_12,
:claim_to_1, :claim_to_2, :claim_to_3, :claim_to_4, :claim_to_5, :claim_to_6,
:claim_to_7, :claim_to_8, :claim_to_9, :claim_to_10, :claim_to_11, :claim_to_12,
:precert_1, :precert_2, :precert_3, :precert_4
)
selected_attributes = employer_attributes.merge(rx_attributes).merge(provider_attributes)
# blank_card.assign_attributes(selected_attributes)
IdCard::PrintData.new(selected_attributes)
end
def create_plan_base_cards(common_fields_card)
needed_plans_ids = @employer.members.where(pb_entity_key: @member_keys).distinct.pluck(:id_card_plan_id)
needed_plans = @card_setup.plans.where(id: needed_plans_ids)
needed_plans.each do |plan|
selected_attributes = { plan_id: plan.id }
plan.plan_benefits.each do |bene|
selected_attributes["benefit_desc_#{bene.sequence}".to_sym] = bene.benefit_desc
selected_attributes["benefit_#{bene.sequence}".to_sym] = bene.benefit
end
plan_base_card = common_fields_card.dup
plan_base_card.assign_attributes(selected_attributes)
plan_base_card.save
end
end
def create_member_cards_async
field_exceptions_map = @card_setup.field_exceptions_card_attributes_by_member_id(@member_keys)
mmember_card_futures = @member_keys.map do |member_key|
member_card_exceptions_attrs = {}
member_card_exception_id = field_exceptions_map[member_key]
if member_card_exception_id
member_card_exceptions_attrs = field_exceptions_map[member_card_exception_id]
end
Concurrent::Future.execute do
ActiveRecord::Base.connection_pool.with_connection do
ProcessMemberCardDataJob.perform_now(member_key, member_card_exceptions_attrs, @card_setup.has_divisions, @card_setup.has_dental)
end
end
end
mmember_card_futures
# batch_process = BatchProcess.create!(total_jobs: @member_keys.count)
# @member_keys.each do |member_key|
# ProcessIdCardDataJob.perform_later(member_key, @card_setup.has_divisions, batch_process.id)
# end
# @batch_id = batch_process.id
# @members.each do |me|
# effect_date = determine_eff_date(me)
# if effect_date
# member_card = @base_card.dup
# member_attributes = {
# full_name: me.id_card_display_name,
# full_name_last_name_first: me.name,
# primary_mb_member_key: me.pb_entity_key,
# family_id: me.family_id,
# plan_id: me.id_card_plan_id,
# medical_eff_date: effect_date.strftime("%m/%d/%Y")
# }
# if @card_setup.has_divisions
# member_attributes.merge!({employer_name: me.division})
# end
# dependent_attributes = get_dependent_fields(me)
# if dependent_attributes.present?
# selected_attributes = member_attributes.merge(dependent_attributes)
# else
# selected_attributes = member_attributes
# end
# member_card.assign_attributes(selected_attributes)
# @employer_cards.push(member_card)
# end
# end
end
# def set_network_fields
# selected_attributes = @employer.card_provider.attributes.with_indifferent_access.slice(
# :provider_line_1, :provider_line_2, :provider_line_3, :provider_line_4, :provider_line_5, :provider_line_6,
# :provider_line_7, :provider_line_8, :provider_line_9, :provider_line_10, :provider_line_11, :provider_line_12,
# :claim_to_1, :claim_to_2, :claim_to_3, :claim_to_4, :claim_to_5, :claim_to_6,
# :claim_to_7, :claim_to_8, :claim_to_9, :claim_to_10, :claim_to_11, :claim_to_12
# )
# @employer_cards.all do |card|
# card.assign_attributes(selected_attributes)
# end
# end
# def set_rx_fields
# # fairos_information = Vhcs::HlrxCrosRef.where(pl_plan_key: 52).first
# selected_attributes = @employer.card_rx.attributes.with_indifferent_access.slice(
# :customer_service,
# :web_url
# )
# @employer_cards.all do |card|
# card.assign_attributes(selected_attributes)
# end
# end
def determine_eff_date(member)
participation = Vhcs::PbProductParticipation.joins('INNER JOIN "PBCoveredEntities" ON "PBProductParticipation"."PBProductParticipationKey" = "PBCoveredEntities"."PBProductParticipationKey"').where('"PBCoveredEntities"."PBEntityKey" = ?', member.pb_entity_key).last
in_effect = participation.in_effect
out_of_effect = participation.out_of_effect
if in_effect <= (Date.today + 90.days) && (out_of_effect - 1.day) > Date.today && out_of_effect > in_effect
in_effect
else
false
end
end
def get_dependent_fields(member)
dependent_attributes = {}
dependents = @group_dependents.where(family_id: member.family_id).where.not(pb_entity_key: member.pb_entity_key)
dependents.each do |dep|
dependent_name = dep.first_name + ' ' + dep.last_name
dependent_attributes["dependent_#{dep.sequence_number - 1}".to_sym] = dependent_name
end
dependent_attributes
end
end
end
@@ -0,0 +1,128 @@
module IdCardPrinterService
class CardsGenerator
def initialize(employers_member_keys, layout, zip=false)
@employers_member_keys = Array.wrap(employers_member_keys)
@layout = layout
@zip = zip
end
def call
pl_plan_keys = @employers_member_keys.map { |emk| emk[:pl_plan_key] }
IdCard::PrintData.where(pl_plan_key: pl_plan_keys).destroy_all
IdCardPrinterService::CardDataFormatter.new(@employers_member_keys).call
IdCard::PrintData.where(pl_plan_key: pl_plan_keys, primary_mb_member_key: nil).destroy_all
pdf_array = []
template_groups = break_up_by_template(pl_plan_keys)
template_groups.each do |card_template, template_pl_plan_keys|
batch = IdCard::PrintData.where(pl_plan_key: template_pl_plan_keys)
# all_template_cards.in_batches(of: 75).each_with_index do |batch, index|
jasper_batch_id = "#{template_pl_plan_keys.join('_')}-#{Time.current.utc.to_i}"
# binding.pry
batch.update!(jasper_batch_id: jasper_batch_id)
if @layout == "PrintCard"
add_dependent_cards(batch)
end
batch_pdf = IdCardPrinterService::PdfBatchProcessor.new(card_template, jasper_batch_id, @layout).call
pdf_array << batch_pdf
# end
# jasper_batches = break_into_jasper_batches(group_pl_plan_keys)
# jasper_batches.each_with_index do |batch, index|
# jasper_batch_id = "#{group_pl_plan_keys.join('_')}-#{index + 1}-#{Time.current.utc.to_i}"
# binding.pry
# batch.update!(jasper_batch_id: jasper_batch_id)
# if @layout == "PrintCard"
# add_dependent_cards(batch)
# end
# batch_pdf = IdCardPrinterService::PdfBatchProcessor.new(card_template, jasper_batch_id, @layout).call
# pdf_array << batch_pdf
# end
end
# @employers_member_keys.each do |emk|
# employer_jasper_batches = IdCard::PrintData.where(pl_plan_key: emk[:pl_plan_key]).pluck(:network_logo_id).uniq
# employer_jasper_batches.each do |batch_network_logo|
# jasper_batch_id = "#{emk[:pl_plan_key]}-#{Time.current.utc.to_i}"
# batch = IdCard::PrintData.where(pl_plan_key: emk[:pl_plan_key], network_logo_id: batch_network_logo)
# # batch = employer_card_data.where(network_logo_id: batch_network_logo)
# batch.update!(jasper_batch_id: jasper_batch_id)
# batch_pdf = IdCardPrinterService::PdfBatchProcessor.new(emk[:pl_plan_key], batch_network_logo, jasper_batch_id, @layout).call
# pdf_array << batch_pdf
# end
# end
group_pdfs = combine_pdfs(pdf_array)
group_pdfs
end
private
def break_up_by_template(pl_plan_keys)
batches_by_card_template = IdCard::Setup.where(pl_plan_key: pl_plan_keys).group_by(&:card_template)
.transform_values { |setups| setups.map(&:pl_plan_key) }
.compact_blank
end
def break_into_jasper_batches(pl_plan_keys)
all_cards = IdCard::PrintData.where(pl_plan_key: pl_plan_keys)
binding.pry
jasper_batches = all_cards.each_slice(75).to_a
jasper_batches
end
def add_dependent_cards(batch)
batch.where.not(dependent_1: [nil, ""]).find_each do |member_card|
dependent_card = member_card.dup
dependent_card.update(
full_name_last_name_first: member_card.full_name_last_name_first.concat(" dependent")
)
dependent_card.save
end
end
def combine_pdfs(pdf_array)
if @zip
group_cards_pdf = Zip::OutputStream.write_buffer do |zio|
pdf_file = pdf_array.first
puts "-- CombinePdfPages --"
puts pdf_file.pages.count
pdf_file.pages.reverse.each do |page|
page_pdf = CombinePDF.new
page_pdf << page
page_data = page_pdf.to_pdf
full_name_last_name_first = get_watermark_field(page_data)
if full_name_last_name_first.present?
page_filename = "#{full_name_last_name_first.gsub(", ", "_")}_digital_card_#{Date.today}.pdf"
puts "-- Filename --"
puts page_filename
zio.put_next_entry(page_filename)
zio.write(page_data)
end
end
end
else
group_cards_pdf = CombinePDF.new
pdf_array.each { |pdf| group_cards_pdf << pdf }
end
group_cards_pdf
end
def get_watermark_field(page_data)
watermark_field = ""
reader = PDF::Reader.new(StringIO.new(page_data))
puts "-- ReaderPages --"
puts reader.pages.count
page = reader.pages.first
if watermark_match = page.text.match(/:WATERMARK:([^:]*):/)
watermark_field = page.text.match(/:WATERMARK:([^:]*):/)[1].strip
else
puts "blank page"
end
watermark_field
end
end
end
@@ -0,0 +1,61 @@
module IdCardPrinterService
class EmployerCardsGenerator
def initialize(employer, layout, zip=false)
@employer = employer
@member_keys = @employer.members.pluck(:pb_entity_key)
@layout = layout
@zip = zip
end
def call
IdCard::PrintData.where(pl_plan_key: @employer.pl_plan_key).destroy_all
IdCardPrinterService::EmployerDataFormatter.new(@employer.pl_plan_key, @member_keys).call
# card_futures.each(&:value)
# max_retries = 60
# retries = 0
# finished = false
# batch_process = BatchProcess.find(batch_id)
# until finished || retries > max_retries
# # Solid Queue stores finished jobs here if preserve_finished_jobs = true
# if batch_process.completed_jobs < batch_process.total_jobs
# sleep 0.5
# retries += 1
# else
# batch_process.destroy!
# finished = true
# end
# end
IdCard::PrintData.where(pl_plan_key: @employer.pl_plan_key, primary_mb_member_key: nil).destroy_all
pdf_array = IdCardPrinterService::PdfProcessor.new(@employer, @layout, @zip).call
group_pdfs = combine_pdfs(pdf_array)
group_pdfs
end
private
def combine_pdfs(pdf_array)
if @zip
group_cards_pdf = Zip::OutputStream.write_buffer do |zio|
pdf_array.each do |file|
zio.put_next_entry(file[:name])
zio.write(file[:data])
end
end
else
group_cards_pdf = CombinePDF.new
pdf_array.each { |pdf| group_cards_pdf << pdf }
end
group_cards_pdf
end
end
end
@@ -0,0 +1,167 @@
module IdCardPrinterService
class EmployerDataFormatter
def initialize(pl_plan_key, member_keys)
# @employer = employer
@member_keys = member_keys
@employer = Employer.includes(id_card_setup: [:provider_section, :rx_section]).find_by(pl_plan_key: pl_plan_key)
@card_setup = @employer.id_card_setup
@batch_id
end
def call
# blank_card = IdCard::PrintData.new()
# @employer_cards = []
base_card = initialize_employer_base_card()
create_plan_base_cards(base_card)
card_futures = create_member_cards_async()
card_futures
end
private
def initialize_employer_base_card
employer_attributes = {
pl_plan_key: @employer.pl_plan_key,
group_number: @employer.group_number,
rx_group: @card_setup.rx_group_number,
network_provider: @card_setup.network_provider
}
unless @card_setup.has_divisions
employer_attributes.merge!({employer_name: @card_setup.print_name})
end
rx_attributes = @card_setup.rx_section.attributes.with_indifferent_access.slice(
:customer_service,
:web_url
)
provider_attributes = @card_setup.provider_section.attributes.with_indifferent_access.slice(
:provider_line_1, :provider_line_2, :provider_line_3, :provider_line_4, :provider_line_5, :provider_line_6,
:provider_line_7, :provider_line_8, :provider_line_9, :provider_line_10, :provider_line_11, :provider_line_12,
:claim_to_1, :claim_to_2, :claim_to_3, :claim_to_4, :claim_to_5, :claim_to_6,
:claim_to_7, :claim_to_8, :claim_to_9, :claim_to_10, :claim_to_11, :claim_to_12
)
selected_attributes = employer_attributes.merge(rx_attributes).merge(provider_attributes)
# blank_card.assign_attributes(selected_attributes)
IdCard::PrintData.new(selected_attributes)
end
def create_plan_base_cards(common_fields_card)
needed_plans_ids = @employer.members.where(pb_entity_key: @member_keys).distinct.pluck(:id_card_plan_id)
needed_plans = @card_setup.plans.where(id: needed_plans_ids)
needed_plans.each do |plan|
selected_attributes = { plan_id: plan.id }
plan.plan_benefits.each do |bene|
selected_attributes["benefit_desc_#{bene.sequence}".to_sym] = bene.benefit_desc
selected_attributes["benefit_#{bene.sequence}".to_sym] = bene.benefit
end
plan_base_card = common_fields_card.dup
plan_base_card.assign_attributes(selected_attributes)
plan_base_card.save
end
end
def create_member_cards_async
mmember_card_futures = @member_keys.map do |member_key|
Concurrent::Future.execute do
ActiveRecord::Base.connection_pool.with_connection do
ProcessIdCardDataJob.perform_now(member_key, @card_setup.has_divisions)
end
end
end
mmember_card_futures
# batch_process = BatchProcess.create!(total_jobs: @member_keys.count)
# @member_keys.each do |member_key|
# ProcessIdCardDataJob.perform_later(member_key, @card_setup.has_divisions, batch_process.id)
# end
# @batch_id = batch_process.id
# @members.each do |me|
# effect_date = determine_eff_date(me)
# if effect_date
# member_card = @base_card.dup
# member_attributes = {
# full_name: me.id_card_display_name,
# full_name_last_name_first: me.name,
# primary_mb_member_key: me.pb_entity_key,
# family_id: me.family_id,
# plan_id: me.id_card_plan_id,
# medical_eff_date: effect_date.strftime("%m/%d/%Y")
# }
# if @card_setup.has_divisions
# member_attributes.merge!({employer_name: me.division})
# end
# dependent_attributes = get_dependent_fields(me)
# if dependent_attributes.present?
# selected_attributes = member_attributes.merge(dependent_attributes)
# else
# selected_attributes = member_attributes
# end
# member_card.assign_attributes(selected_attributes)
# @employer_cards.push(member_card)
# end
# end
end
# def set_network_fields
# selected_attributes = @employer.card_provider.attributes.with_indifferent_access.slice(
# :provider_line_1, :provider_line_2, :provider_line_3, :provider_line_4, :provider_line_5, :provider_line_6,
# :provider_line_7, :provider_line_8, :provider_line_9, :provider_line_10, :provider_line_11, :provider_line_12,
# :claim_to_1, :claim_to_2, :claim_to_3, :claim_to_4, :claim_to_5, :claim_to_6,
# :claim_to_7, :claim_to_8, :claim_to_9, :claim_to_10, :claim_to_11, :claim_to_12
# )
# @employer_cards.all do |card|
# card.assign_attributes(selected_attributes)
# end
# end
# def set_rx_fields
# # fairos_information = Vhcs::HlrxCrosRef.where(pl_plan_key: 52).first
# selected_attributes = @employer.card_rx.attributes.with_indifferent_access.slice(
# :customer_service,
# :web_url
# )
# @employer_cards.all do |card|
# card.assign_attributes(selected_attributes)
# end
# end
def determine_eff_date(member)
participation = Vhcs::PbProductParticipation.joins('INNER JOIN "PBCoveredEntities" ON "PBProductParticipation"."PBProductParticipationKey" = "PBCoveredEntities"."PBProductParticipationKey"').where('"PBCoveredEntities"."PBEntityKey" = ?', member.pb_entity_key).last
in_effect = participation.in_effect
out_of_effect = participation.out_of_effect
if in_effect <= (Date.today + 90.days) && (out_of_effect - 1.day) > Date.today && out_of_effect > in_effect
in_effect
else
false
end
end
def get_dependent_fields(member)
dependent_attributes = {}
dependents = @group_dependents.where(family_id: member.family_id).where.not(pb_entity_key: member.pb_entity_key)
dependents.each do |dep|
dependent_name = dep.first_name + ' ' + dep.last_name
dependent_attributes["dependent_#{dep.sequence_number - 1}".to_sym] = dependent_name
end
dependent_attributes
end
end
end
@@ -0,0 +1,40 @@
module IdCardPrinterService
class JasperBatchUrlGenerator
def initialize(card_template, jasper_batch_id, layout)
@card_template = card_template
@jasper_batch_id = jasper_batch_id
@layout = layout
end
def call
URI::HTTP.build(url_components)
end
private
# def determine_network_logo
# # if @network_logos.length > 1
# # member_geographic_info = Vhcs::PbEntityAddress.joins("INNER JOIN vwMBMember ON PBEntityAddress.PBEntityKey = vwMBMember.PBEntityKey AND PBEntityAddress.AddressTypeID = 1137").where("vwMBMember.FamilyID = ?", @family_id).first
# # @network_logos.where.not(default: true).each do |pnl|
# # if member_geographic_info[pnl.exception_type] == pnl.exception_value
# # return pnl.net_logo
# # end
# # end
# # end
# # @network_logos.find_by(default: true).net_logo
# IdCard::NetworkLogo.find(@network_logo_id).filename
# end
# http://localhost:8080/trunk/PdfServlet?reportConn=BrittonConnect&id=&reportName=FairosRxSampleIDCard-Half&family_id=Classic%202K&employer_logo=BryanPestControl.jpeg&network_logo=CignaLogo.png&reportDir=secure/Documents&SUBREPORT_DIR=/&ImageDir=secure/Documents&netToken=3a4a8b03f4dfb0e6e3fc82dd369f70ef&FileType=PDF
# http://localhost:8080/trunk/PdfServlet?reportConn=BrittonConnect&id=&reportName=FairosRxSampleIDCard-Half&family_id=Classic%202K&employer_logo=BryanPestControl.jpeg&network_logo=CignaLogo.png&reportDir=secure/Documents&SUBREPORT_DIR=/&ImageDir=secure/Documents&netToken=3a4a8b03f4dfb0e6e3fc82dd369f70ef&FileType=PDF
def url_components
{
host: '10.41.1.115',
port: 8080,
path: '/trunk/IdCardsServlet',
query: "reportConn=BrittonConnect&cardTemplate=#{@card_template}&printType=#{@layout}&jasper_batch_id=#{@jasper_batch_id}&FileType=PDF"
}
end
end
end

Some files were not shown because too many files have changed in this diff Show More