Compare commits

23 Commits

Author SHA1 Message Date
Jason Jordan 5a90ea6e14 beta build 2026-06-17 23:23:36 -04:00
Jason Jordan 5f04811c16 asset compilation 2026-05-06 17:21:06 -04:00
Jason Jordan 518522b080 updated dockerbuild for icons 5 2026-05-06 17:13:27 -04:00
Jason Jordan 826ef02322 updated dockerbuild for icons 4 2026-05-06 17:08:48 -04:00
Jason Jordan d25d5c9bba updated dockerbuild for icons 3 2026-05-06 16:38:37 -04:00
Jason Jordan 6c3649ad61 updated dockerbuild for icons 2 2026-05-06 16:29:07 -04:00
Jason Jordan f35cc99a0f updated dockerbuild for icons 2026-05-06 16:11:02 -04:00
Jason Jordan 34843e2da7 prod pruning 2 2026-05-06 15:14:51 -04:00
Jason Jordan 3bf9594842 prod pruning 2026-05-06 15:07:57 -04:00
Jason Jordan e0101be567 Prod build process 2026-05-06 13:28:16 -04:00
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
384 changed files with 132621 additions and 7690 deletions
+2
View File
@@ -0,0 +1,2 @@
/app/assets/builds/*
/app/assets/svg/*
-3
View File
@@ -1,3 +0,0 @@
PGHOST=db
PGUSER=postgres
PGPASSWORD=changeme
+12 -1
View File
@@ -74,6 +74,17 @@ yarn-debug.log*
.DS_Store .DS_Store
/app/assets/builds/* /app/assets/builds/*
/app/assets/svg/*
!/app/assets/builds/.keep !/app/assets/builds/.keep
/mssql-data /mssql-data
/logo_files
/employer_word_docs
# Ignore application configuration
/config/application.yml
/scratch.rb
/start_rails.bat
/web.config
/db/old
+1 -1
View File
@@ -7,7 +7,7 @@ inherit_gem:
rubocop-rails-omakase: rubocop.yml rubocop-rails-omakase: rubocop.yml
AllCops: AllCops:
TargetRubyVersion: 3.3.9 TargetRubyVersion: 3.4.8
TargetRailsVersion: 7.2.2 TargetRailsVersion: 7.2.2
DisabledByDefault: true DisabledByDefault: true
Exclude: Exclude:
+1 -1
View File
@@ -1 +1 @@
3.3.9 3.4.8
+55 -44
View File
@@ -1,73 +1,84 @@
# syntax=docker/dockerfile:1 # syntax = docker/dockerfile:1
# check=error=true
# This Dockerfile is designed for production, not development. # 1. Base Stage: Common dependencies
# docker build -t my-app . ARG RUBY_VERSION=3.4.8
# docker run -d -p 80:80 -p 443:443 --name my-app -e RAILS_MASTER_KEY=<value from config/master.key> my-app FROM ruby:$RUBY_VERSION-slim as base
# Make sure RUBY_VERSION matches the Ruby version in .ruby-version and Gemfile
ARG RUBY_VERSION=3.3.9
FROM docker.io/library/ruby:$RUBY_VERSION-slim AS base
# Rails app lives here
WORKDIR /rails WORKDIR /rails
# Install base packages
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y curl libjemalloc2 libvips postgresql-client && \
rm -rf /var/lib/apt/lists /var/cache/apt/archives
# Set production environment
ENV RAILS_ENV="production" \ ENV RAILS_ENV="production" \
BUNDLE_DEPLOYMENT="1" \ BUNDLE_DEPLOYMENT="1" \
BUNDLE_PATH="/usr/local/bundle" \ BUNDLE_PATH="/usr/local/bundle" \
BUNDLE_WITHOUT="development" BUNDLE_WITHOUT="development:test"
# Throw-away build stage to reduce size of final image # Install base packages (libvips for Active Storage, curl for healthchecks)
FROM base AS build
# Install packages needed to build gems
RUN apt-get update -qq && \ RUN apt-get update -qq && \
apt-get install --no-install-recommends -y build-essential git libpq-dev pkg-config libyaml-dev && \ apt-get install --no-install-recommends -y \
curl \
git \
libvips \
freetds-bin \
freetds-dev \
libpq-dev \
libyaml-dev \
cron \
libjemalloc2 \
dos2unix && \
rm -rf /var/lib/apt/lists /var/cache/apt/archives rm -rf /var/lib/apt/lists /var/cache/apt/archives
# 2. Build Stage: Gems and Assets
FROM base as build
# Install packages needed to build gems and precompile assets
RUN apt-get update -qq && \
apt-get install --no-install-recommends -y build-essential pkg-config less && \
# mkdir -p /etc/apt/keyrings && \
# curl -fsSL https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key | gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg && \
# echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_20.x nodistro main" > /etc/apt/sources.list.d/nodesource.list && \
# apt-get update && \
# apt-get install nodejs -y && \
rm -rf /var/lib/apt/lists /var/cache/apt/archives
# RUN apt-get install -y npm
# RUN npm install -g yarn
# Install application gems # Install application gems
RUN bundle config set --local frozen false
COPY Gemfile Gemfile.lock ./ COPY Gemfile Gemfile.lock ./
RUN bundle install && \ RUN bundle install && \
rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git && \ rm -rf ~/.bundle/ "${BUNDLE_PATH}"/ruby/*/cache "${BUNDLE_PATH}"/ruby/*/bundler/gems/*/.git
bundle exec bootsnap precompile --gemfile
# Copy application code # Copy application code
COPY . . COPY . .
# Precompile bootsnap code for faster boot times RUN ./bin/rails stimulus:manifest:update
RUN bundle exec bootsnap precompile app/ lib/ RUN ./bin/importmap pin .
# Precompiling assets for production without requiring secret RAILS_MASTER_KEY # RUN bundle exec ./bin/rails rails_icons:sync
RUN SECRET_KEY_BASE_DUMMY=1 ./bin/rails assets:precompile RUN ./bin/rails generate rails_icons:sync --libraries=lucide
# Precompile assets (Tailwind is triggered here via assets:precompile)
# SECRET_KEY_BASE_DUMMY allows precompilation without real secrets
# RUN bundle exec rails assets:clobber assets:precompile RAILS_ENV=production SECRET_KEY_BASE_DUMMY=1
RUN bundle exec rails assets:precompile RAILS_ENV=production SECRET_KEY_BASE_DUMMY=1
# Final stage for app image # 3. Final Stage: Lean Runtime
FROM base FROM base
# Copy built artifacts: gems, application # Copy built artifacts: gems and precompiled assets
COPY --from=build "${BUNDLE_PATH}" "${BUNDLE_PATH}" # COPY --from=build /rails/public /rails/public
# COPY --from=build /rails/app/javascript /rails/app/javascript
# COPY --from=build /rails/config/importmap.rb /rails/config/importmap.rb
COPY --from=build /usr/local/bundle /usr/local/bundle
COPY --from=build /rails /rails COPY --from=build /rails /rails
# Run and own only the runtime files as a non-root user for security # Run as a non-privileged user for security
RUN groupadd --system --gid 1000 rails && \ RUN useradd -ms /bin/bash rails
useradd rails --uid 1000 --gid 1000 --create-home --shell /bin/bash && \ RUN chown -R rails:rails /rails
chown -R rails:rails db log storage tmp USER rails:rails
USER 1000:1000
# Entrypoint prepares the database. # Entrypoint prepares the database.
ENTRYPOINT ["/rails/bin/docker-entrypoint"] ENTRYPOINT ["/rails/bin/docker-entrypoint"]
HEALTHCHECK --interval=15s --timeout=3s --start-period=0s --start-interval=5s --retries=3 \ # Start the server
CMD curl -f http://localhost:3000/up || exit 1 EXPOSE 3002
# Start the server by default, this can be overwritten at runtime
EXPOSE 3000
# The default Rails Dockerfile uses `./bin/rails server`, but when using Puma,
# they recommend using bundle exec puma. ref: https://github.com/puma/puma#rails
CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"] CMD ["bundle", "exec", "puma", "-C", "config/puma.rb"]
+12 -3
View File
@@ -3,7 +3,7 @@
source "https://rubygems.org" source "https://rubygems.org"
git_source(:github) { |repo| "https://github.com/#{repo}.git" } git_source(:github) { |repo| "https://github.com/#{repo}.git" }
ruby "3.3.9" ruby "3.4.8"
# Bundle edge Rails instead: # Bundle edge Rails instead:
# gem "rails", github: "rails/rails", branch: "7-2-stable" # gem "rails", github: "rails/rails", branch: "7-2-stable"
@@ -83,8 +83,17 @@ gem 'devise'
gem 'pundit' gem 'pundit'
gem "tailwindcss-rails" gem "tailwindcss-rails"
gem 'docx' gem 'docx'
gem 'rubyzip'
gem 'httparty' gem 'httparty'
gem 'combine_pdf' gem 'combine_pdf'
gem 'pdf-reader'
gem 'rails_icons' gem 'rails_icons'
gem 'fastimage' gem 'fastimage'
gem 'rubyzip', require: 'zip'
# gem "solid_queue"
gem 'delayed_job_active_record'
gem 'daemons'
gem 'image_processing'
gem "ruby-vips"
gem 'whenever', require: false
gem 'amatch'
gem 'figaro'
+133 -110
View File
@@ -1,6 +1,7 @@
GEM GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
Ascii85 (2.0.1)
actioncable (7.2.3) actioncable (7.2.3)
actionpack (= 7.2.3) actionpack (= 7.2.3)
activesupport (= 7.2.3) activesupport (= 7.2.3)
@@ -56,7 +57,7 @@ GEM
activemodel (= 7.2.3) activemodel (= 7.2.3)
activesupport (= 7.2.3) activesupport (= 7.2.3)
timeout (>= 0.4.0) timeout (>= 0.4.0)
activerecord-sqlserver-adapter (7.2.8) activerecord-sqlserver-adapter (7.2.9)
activerecord (~> 7.2.0) activerecord (~> 7.2.0)
tiny_tds tiny_tds
activestorage (7.2.3) activestorage (7.2.3)
@@ -77,21 +78,25 @@ GEM
minitest (>= 5.1) minitest (>= 5.1)
securerandom (>= 0.3) securerandom (>= 0.3)
tzinfo (~> 2.0, >= 2.0.5) tzinfo (~> 2.0, >= 2.0.5)
addressable (2.8.7) addressable (2.9.0)
public_suffix (>= 2.0.2, < 7.0) public_suffix (>= 2.0.2, < 8.0)
afm (1.0.0)
amatch (0.6.0)
mize
tins (~> 1)
ast (2.4.3) ast (2.4.3)
base64 (0.3.0) base64 (0.3.0)
bcrypt (3.1.20) bcrypt (3.1.22)
benchmark (0.5.0) benchmark (0.5.0)
bigdecimal (3.3.1) bigdecimal (4.1.2)
bindex (0.8.1) bindex (0.8.1)
bootsnap (1.18.6) bootsnap (1.24.3)
msgpack (~> 1.2) msgpack (~> 1.2)
brakeman (7.1.1) brakeman (8.0.4)
racc racc
builder (3.3.0) builder (3.3.0)
bundler-audit (0.9.2) bundler-audit (0.9.3)
bundler (>= 1.2.0, < 3) bundler (>= 1.2.0)
thor (~> 1.0) thor (~> 1.0)
capybara (3.40.0) capybara (3.40.0)
addressable addressable
@@ -102,20 +107,29 @@ GEM
rack-test (>= 0.6.3) rack-test (>= 0.6.3)
regexp_parser (>= 1.5, < 3.0) regexp_parser (>= 1.5, < 3.0)
xpath (~> 3.2) xpath (~> 3.2)
cgi (0.5.0) cgi (0.5.1)
chronic (0.10.2)
coderay (1.1.3) coderay (1.1.3)
combine_pdf (1.0.31) combine_pdf (1.0.31)
matrix matrix
ruby-rc4 (>= 0.1.5) ruby-rc4 (>= 0.1.5)
concurrent-ruby (1.3.5) concurrent-ruby (1.3.6)
connection_pool (2.5.4) connection_pool (3.0.2)
crass (1.0.6) crass (1.0.6)
csv (3.3.5) csv (3.3.5)
date (3.5.0) daemons (1.4.1)
devise (4.9.4) date (3.5.1)
delayed_job (4.2.0)
activesupport (>= 3.0, < 9.0)
benchmark
logger
delayed_job_active_record (4.1.11)
activerecord (>= 3.0, < 9.0)
delayed_job (>= 3.0, < 5)
devise (5.0.3)
bcrypt (~> 3.0) bcrypt (~> 3.0)
orm_adapter (~> 0.1) orm_adapter (~> 0.1)
railties (>= 4.1.0) railties (>= 7.0)
responders responders
warden (~> 1.2.3) warden (~> 1.2.3)
diff-lcs (1.6.2) diff-lcs (1.6.2)
@@ -123,34 +137,44 @@ GEM
nokogiri (~> 1.13, >= 1.13.0) nokogiri (~> 1.13, >= 1.13.0)
rubyzip (>= 2.0, < 4) rubyzip (>= 2.0, < 4)
drb (2.2.3) drb (2.2.3)
erb (5.1.3) erb (6.0.4)
erubi (1.13.1) erubi (1.13.1)
fastimage (2.4.0) fastimage (2.4.1)
ffi (1.17.4-x86_64-linux-gnu)
figaro (1.3.0)
thor (>= 0.14.0, < 2)
globalid (1.3.0) globalid (1.3.0)
activesupport (>= 6.1) activesupport (>= 6.1)
httparty (0.23.2) hashery (2.1.2)
httparty (0.24.2)
csv csv
mini_mime (>= 1.0.0) mini_mime (>= 1.0.0)
multi_xml (>= 0.5.2) multi_xml (>= 0.5.2)
i18n (1.14.7) i18n (1.14.8)
concurrent-ruby (~> 1.0) 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) actionpack (>= 6.0.0)
activesupport (>= 6.0.0) activesupport (>= 6.0.0)
railties (>= 6.0.0) railties (>= 6.0.0)
io-console (0.8.1) io-console (0.8.2)
irb (1.15.3) irb (1.18.0)
pp (>= 0.6.0) pp (>= 0.6.0)
prism (>= 1.3.0)
rdoc (>= 4.0.0) rdoc (>= 4.0.0)
reline (>= 0.4.2) reline (>= 0.4.2)
jbuilder (2.14.1) jbuilder (2.14.1)
actionview (>= 7.0.0) actionview (>= 7.0.0)
activesupport (>= 7.0.0) activesupport (>= 7.0.0)
json (2.15.2) json (2.19.5)
language_server-protocol (3.17.0.5) language_server-protocol (3.17.0.5)
lint_roller (1.1.0) lint_roller (1.1.0)
logger (1.7.0) logger (1.7.0)
loofah (2.24.1) loofah (2.25.1)
crass (~> 1.0.2) crass (~> 1.0.2)
nokogiri (>= 1.12.0) nokogiri (>= 1.12.0)
mail (2.9.0) mail (2.9.0)
@@ -162,12 +186,17 @@ GEM
marcel (1.1.0) marcel (1.1.0)
matrix (0.4.3) matrix (0.4.3)
method_source (1.1.0) method_source (1.1.0)
mini_magick (5.3.1)
logger
mini_mime (1.1.5) mini_mime (1.1.5)
minitest (5.26.0) minitest (6.0.6)
drb (~> 2.0)
prism (~> 1.5)
mize (0.6.1)
msgpack (1.8.0) msgpack (1.8.0)
multi_xml (0.7.2) multi_xml (0.9.1)
bigdecimal (~> 3.1) bigdecimal (>= 3.1, < 5)
net-imap (0.5.12) net-imap (0.6.4)
date date
net-protocol net-protocol
net-pop (0.1.2) net-pop (0.1.2)
@@ -177,54 +206,47 @@ GEM
net-smtp (0.5.1) net-smtp (0.5.1)
net-protocol net-protocol
nio4r (2.7.5) nio4r (2.7.5)
nokogiri (1.18.10-aarch64-linux-gnu) nokogiri (1.19.3-x86_64-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)
racc (~> 1.4) racc (~> 1.4)
orm_adapter (0.5.0) orm_adapter (0.5.0)
parallel (1.27.0) parallel (2.1.0)
parser (3.3.10.0) parser (3.3.11.1)
ast (~> 2.4.1) ast (~> 2.4.1)
racc 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) pp (0.6.3)
prettyprint prettyprint
prettyprint (0.2.0) prettyprint (0.2.0)
prism (1.6.0) prism (1.9.0)
pry (0.15.2) pry (0.16.0)
coderay (~> 1.1) coderay (~> 1.1)
method_source (~> 1.0) method_source (~> 1.0)
reline (>= 0.6.0)
pry-rails (0.3.11) pry-rails (0.3.11)
pry (>= 0.13.0) pry (>= 0.13.0)
psych (5.2.6) psych (5.3.1)
date date
stringio stringio
public_suffix (6.0.2) public_suffix (7.0.5)
puma (6.6.1) puma (6.6.1)
nio4r (~> 2.0) nio4r (~> 2.0)
pundit (2.5.2) pundit (2.5.2)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
racc (1.8.1) racc (1.8.1)
rack (3.2.4) rack (3.2.6)
rack-mini-profiler (4.0.1) rack-mini-profiler (4.0.1)
rack (>= 1.2.0) rack (>= 1.2.0)
rack-session (2.1.1) rack-session (2.1.2)
base64 (>= 0.1.0) base64 (>= 0.1.0)
rack (>= 3.0.0) rack (>= 3.0.0)
rack-test (2.2.0) rack-test (2.2.0)
rack (>= 1.3) rack (>= 1.3)
rackup (2.2.1) rackup (2.3.1)
rack (>= 3) rack (>= 3)
rails (7.2.3) rails (7.2.3)
actioncable (= 7.2.3) actioncable (= 7.2.3)
@@ -244,11 +266,11 @@ GEM
activesupport (>= 5.0.0) activesupport (>= 5.0.0)
minitest minitest
nokogiri (>= 1.6) nokogiri (>= 1.6)
rails-html-sanitizer (1.6.2) rails-html-sanitizer (1.7.0)
loofah (~> 2.21) 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) 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) rails_icons (1.8.0)
nokogiri (~> 1.16, >= 1.16.4) icons (~> 0.8.1)
rails (>= 7.0) rails (>= 7.0)
railties (7.2.3) railties (7.2.3)
actionpack (= 7.2.3) actionpack (= 7.2.3)
@@ -261,13 +283,15 @@ GEM
tsort (>= 0.2) tsort (>= 0.2)
zeitwerk (~> 2.6) zeitwerk (~> 2.6)
rainbow (3.1.1) rainbow (3.1.1)
rake (13.3.1) rake (13.4.2)
rdoc (6.15.1) rdoc (7.2.0)
erb erb
psych (>= 4.0.0) psych (>= 4.0.0)
tsort tsort
regexp_parser (2.11.3) readline (0.0.4)
reline (0.6.2) reline
regexp_parser (2.12.0)
reline (0.6.3)
io-console (~> 0.5) io-console (~> 0.5)
responders (3.2.0) responders (3.2.0)
actionpack (>= 7.0) actionpack (>= 7.0)
@@ -278,37 +302,37 @@ GEM
rspec-expectations (3.13.5) rspec-expectations (3.13.5)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0) rspec-support (~> 3.13.0)
rspec-mocks (3.13.7) rspec-mocks (3.13.8)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0) rspec-support (~> 3.13.0)
rspec-rails (8.0.2) rspec-rails (8.0.4)
actionpack (>= 7.2) actionpack (>= 7.2)
activesupport (>= 7.2) activesupport (>= 7.2)
railties (>= 7.2) railties (>= 7.2)
rspec-core (~> 3.13) rspec-core (>= 3.13.0, < 5.0.0)
rspec-expectations (~> 3.13) rspec-expectations (>= 3.13.0, < 5.0.0)
rspec-mocks (~> 3.13) rspec-mocks (>= 3.13.0, < 5.0.0)
rspec-support (~> 3.13) rspec-support (>= 3.13.0, < 5.0.0)
rspec-support (3.13.6) rspec-support (3.13.7)
rubocop (1.81.7) rubocop (1.86.1)
json (~> 2.3) json (~> 2.3)
language_server-protocol (~> 3.17.0.2) language_server-protocol (~> 3.17.0.2)
lint_roller (~> 1.1.0) lint_roller (~> 1.1.0)
parallel (~> 1.10) parallel (>= 1.10)
parser (>= 3.3.0.2) parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0) rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 2.9.3, < 3.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) ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 4.0) unicode-display_width (>= 2.4.0, < 4.0)
rubocop-ast (1.47.1) rubocop-ast (1.49.1)
parser (>= 3.3.7.2) parser (>= 3.3.7.2)
prism (~> 1.4) prism (~> 1.7)
rubocop-performance (1.26.1) rubocop-performance (1.26.1)
lint_roller (~> 1.1) lint_roller (~> 1.1)
rubocop (>= 1.75.0, < 2.0) rubocop (>= 1.75.0, < 2.0)
rubocop-ast (>= 1.47.1, < 2.0) rubocop-ast (>= 1.47.1, < 2.0)
rubocop-rails (2.33.4) rubocop-rails (2.34.3)
activesupport (>= 4.2.0) activesupport (>= 4.2.0)
lint_roller (~> 1.1) lint_roller (~> 1.1)
rack (>= 1.1) rack (>= 1.1)
@@ -318,14 +342,17 @@ GEM
rubocop (>= 1.72) rubocop (>= 1.72)
rubocop-performance (>= 1.24) rubocop-performance (>= 1.24)
rubocop-rails (>= 2.30) rubocop-rails (>= 2.30)
rubocop-rspec (3.7.0) rubocop-rspec (3.9.0)
lint_roller (~> 1.1) lint_roller (~> 1.1)
rubocop (~> 1.72, >= 1.72.1) rubocop (~> 1.81)
ruby-progressbar (1.13.0) ruby-progressbar (1.13.0)
ruby-rc4 (0.1.5) ruby-rc4 (0.1.5)
rubyzip (3.2.2) ruby-vips (2.3.0)
ffi (~> 1.12)
logger
rubyzip (3.3.0)
securerandom (0.4.1) securerandom (0.4.1)
selenium-webdriver (4.38.0) selenium-webdriver (4.43.0)
base64 (~> 0.2) base64 (~> 0.2)
logger (~> 1.4) logger (~> 1.4)
rexml (~> 3.2, >= 3.2.5) rexml (~> 3.2, >= 3.2.5)
@@ -341,38 +368,31 @@ GEM
sprockets (>= 3.0.0) sprockets (>= 3.0.0)
stimulus-rails (1.3.4) stimulus-rails (1.3.4)
railties (>= 6.0.0) railties (>= 6.0.0)
stringio (3.1.7) stringio (3.2.0)
sync (0.5.0)
tailwindcss-rails (4.4.0) tailwindcss-rails (4.4.0)
railties (>= 7.0.0) railties (>= 7.0.0)
tailwindcss-ruby (~> 4.0) tailwindcss-ruby (~> 4.0)
tailwindcss-ruby (4.1.16) tailwindcss-ruby (4.2.4-x86_64-linux-gnu)
tailwindcss-ruby (4.1.16-aarch64-linux-gnu) thor (1.5.0)
tailwindcss-ruby (4.1.16-aarch64-linux-musl) timeout (0.6.1)
tailwindcss-ruby (4.1.16-arm64-darwin) tins (1.53.0)
tailwindcss-ruby (4.1.16-x86_64-darwin) bigdecimal
tailwindcss-ruby (4.1.16-x86_64-linux-gnu) mize (~> 0.6)
tailwindcss-ruby (4.1.16-x86_64-linux-musl) readline
thor (1.4.0) sync
timeout (0.4.4) tiny_tds (3.4.0-x86_64-linux-gnu)
tiny_tds (3.3.0) bigdecimal (>= 2.0.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)
tsort (0.2.0) tsort (0.2.0)
turbo-rails (2.0.20) ttfunk (1.7.0)
turbo-rails (2.0.23)
actionpack (>= 7.1.0) actionpack (>= 7.1.0)
railties (>= 7.1.0) railties (>= 7.1.0)
tzinfo (2.0.6) tzinfo (2.0.6)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
unicode-display_width (3.2.0) unicode-display_width (3.2.0)
unicode-emoji (~> 4.1) unicode-emoji (~> 4.1)
unicode-emoji (4.1.0) unicode-emoji (4.2.0)
useragent (0.16.11) useragent (0.16.11)
warden (1.2.9) warden (1.2.9)
rack (>= 2.0.9) rack (>= 2.0.9)
@@ -386,33 +406,34 @@ GEM
base64 base64
websocket-extensions (>= 0.1.0) websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5) websocket-extensions (0.1.5)
whenever (1.1.2)
chronic (>= 0.6.3)
xpath (3.2.0) xpath (3.2.0)
nokogiri (~> 1.8) nokogiri (~> 1.8)
zeitwerk (2.7.3) zeitwerk (2.7.5)
PLATFORMS PLATFORMS
aarch64-linux-gnu x86_64-linux
aarch64-linux-musl
arm-linux-gnu
arm-linux-musl
arm64-darwin
x86_64-darwin
x86_64-linux-gnu
x86_64-linux-musl
DEPENDENCIES DEPENDENCIES
activerecord-sqlserver-adapter activerecord-sqlserver-adapter
amatch
bootsnap bootsnap
brakeman brakeman
bundler-audit bundler-audit
capybara capybara
combine_pdf combine_pdf
daemons
delayed_job_active_record
devise devise
docx docx
fastimage fastimage
figaro
httparty httparty
image_processing
importmap-rails importmap-rails
jbuilder jbuilder
pdf-reader
pry-rails pry-rails
puma (~> 6.5) puma (~> 6.5)
pundit pundit
@@ -423,6 +444,7 @@ DEPENDENCIES
rubocop-rails rubocop-rails
rubocop-rails-omakase rubocop-rails-omakase
rubocop-rspec rubocop-rspec
ruby-vips
rubyzip rubyzip
selenium-webdriver selenium-webdriver
sprockets-rails sprockets-rails
@@ -432,9 +454,10 @@ DEPENDENCIES
turbo-rails turbo-rails
tzinfo-data tzinfo-data
web-console web-console
whenever
RUBY VERSION RUBY VERSION
ruby 3.3.9p170 ruby 3.4.8p72
BUNDLED WITH BUNDLED WITH
2.5.22 2.6.9
+7
View File
@@ -19,6 +19,9 @@
--color-cobalt: #0047AB; --color-cobalt: #0047AB;
/* cobalt blue */ /* cobalt blue */
--color-cobalt-tinted: #003B8F; --color-cobalt-tinted: #003B8F;
/* cobalt blue */
--color-cobalt-vivid: #005DE0;
/* #3388FF */
/* platinum */ /* platinum */
--color-platinum: #E0E0E0; --color-platinum: #E0E0E0;
/* copper */ /* copper */
@@ -33,6 +36,10 @@
--color-verdigris: #588288; --color-verdigris: #588288;
/* oxidized copper/bronze green-blue */ /* oxidized copper/bronze green-blue */
--color-verdigris-tinted: #496A6F; --color-verdigris-tinted: #496A6F;
/* oxidized copper/bronze green-blue */
--color-verdigris-vivid: #618D94;
/* alert red */ /* alert red */
--color-brightlava: #f80800; --color-brightlava: #f80800;
/* alert green */
--color-limegreen: #32CD32;
} }
+11
View File
@@ -1,4 +1,15 @@
# frozen_string_literal: true # frozen_string_literal: true
class ApplicationController < ActionController::Base class ApplicationController < ActionController::Base
include Pundit::Authorization
before_action :authenticate_user!
def after_sign_in_path_for(resource)
stored_location_for(resource) || dashboard_path
end
def after_sign_out_path_for(resource_or_scope)
root_path
end
end end
-69
View File
@@ -1,69 +0,0 @@
class ArticlesController < ApplicationController
before_action :set_article, only: %i[ show edit update destroy ]
# GET /articles or /articles.json
def index
@articles = Article.all
end
# GET /articles/1 or /articles/1.json
def show
end
# GET /articles/new
def new
@article = Article.new
end
# GET /articles/1/edit
def edit
end
# POST /articles or /articles.json
def create
@article = Article.new(article_params)
respond_to do |format|
if @article.save
format.html { redirect_to @article, notice: "Article was successfully created." }
format.json { render :show, status: :created, location: @article }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @article.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /articles/1 or /articles/1.json
def update
respond_to do |format|
if @article.update(article_params)
format.html { redirect_to @article, notice: "Article was successfully updated." }
format.json { render :show, status: :ok, location: @article }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: @article.errors, status: :unprocessable_entity }
end
end
end
# DELETE /articles/1 or /articles/1.json
def destroy
@article.destroy
respond_to do |format|
format.html { redirect_to articles_url, notice: "Article was successfully destroyed." }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_article
@article = Article.find(params[:id])
end
# Only allow a list of trusted parameters through.
def article_params
params.require(:article).permit(:title, :content)
end
end
+70
View File
@@ -0,0 +1,70 @@
class BrokersController < ApplicationController
before_action :set_broker, only: %i[ show edit update destroy ]
# GET /brokers or /brokers.json
def index
@brokers = Broker.all
end
# GET /brokers/1 or /brokers/1.json
def show
end
# GET /brokers/new
def new
@broker = Broker.new
end
# GET /brokers/1/edit
def edit
end
# POST /brokers or /brokers.json
def create
@broker = Broker.new(broker_params)
respond_to do |format|
if @broker.save
format.html { redirect_to @broker, notice: "Broker was successfully created." }
format.json { render :show, status: :created, location: @broker }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @broker.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /brokers/1 or /brokers/1.json
def update
respond_to do |format|
if @broker.update(broker_params)
format.html { redirect_to @broker, notice: "Broker was successfully updated.", status: :see_other }
format.json { render :show, status: :ok, location: @broker }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: @broker.errors, status: :unprocessable_entity }
end
end
end
# DELETE /brokers/1 or /brokers/1.json
def destroy
@broker.destroy!
respond_to do |format|
format.html { redirect_to brokers_path, notice: "Broker was successfully destroyed.", status: :see_other }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_broker
@broker = Broker.find(params[:id])
end
# Only allow a list of trusted parameters through.
def broker_params
params.require(:broker).permit(:name, :carrier_id)
end
end
@@ -1,57 +0,0 @@
class CardLogoFilesController < ApplicationController
def index
end
def show
end
def image
logo_file = CardLogoFile.find_by(filename: params[:id])
puts params[:id]
logo_binary = logo_file.image_data
logo_filename = logo_file.filename
logo_file_type = logo_file.content_type
send_data logo_binary,
filename: logo_filename,
# type: logo_file_type,
disposition: 'inline'
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,70 +0,0 @@
class CardProvidersController < ApplicationController
before_action :set_card_provider, only: %i[ show edit update destroy ]
# GET /card_providers or /card_providers.json
def index
@card_providers = CardProvider.all
end
# GET /card_providers/1 or /card_providers/1.json
def show
end
# GET /card_providers/new
def new
@card_provider = CardProvider.new
end
# GET /card_providers/1/edit
def edit
end
# POST /card_providers or /card_providers.json
def create
@card_provider = CardProvider.new(card_provider_params)
respond_to do |format|
if @card_provider.save
format.html { redirect_to @card_provider, notice: "Card provider was successfully created." }
format.json { render :show, status: :created, location: @card_provider }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @card_provider.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /card_providers/1 or /card_providers/1.json
def update
respond_to do |format|
if @card_provider.update(card_provider_params)
format.html { redirect_to @card_provider, notice: "Card provider was successfully updated.", status: :see_other }
format.json { render :show, status: :ok, location: @card_provider }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: @card_provider.errors, status: :unprocessable_entity }
end
end
end
# DELETE /card_providers/1 or /card_providers/1.json
def destroy
@card_provider.destroy!
respond_to do |format|
format.html { redirect_to card_providers_path, notice: "Card provider was successfully destroyed.", status: :see_other }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_card_provider
@card_provider = CardProvider.find(params[:id])
end
# Only allow a list of trusted parameters through.
def card_provider_params
params.require(:card_provider).permit(:provider_code, :provider_line_1, :provider_line_2, :provider_line_3, :provider_line_4, :provider_line_5, :mail_to, :mail_to_2, :contact_line_1, :contact_line_2, :contact_line_3, :group_number, :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, :provider_line_6, :provider_line_7, :provider_line_8, :provider_line_9, :provider_line_10, :provider_line_11, :rx_group_id, :rx_contact, :provider_lookup_1, :provider_lookup_2, :precert_1, :precert_2, :precert_3, :precert_4, :precert_5, :precert_6, :provider_line_12, :claim_to_12)
end
end
-70
View File
@@ -1,70 +0,0 @@
class CardRxesController < ApplicationController
before_action :set_card_rx, only: %i[ show edit update destroy ]
# GET /card_rxes or /card_rxes.json
def index
@card_rxes = CardRx.all
end
# GET /card_rxes/1 or /card_rxes/1.json
def show
end
# GET /card_rxes/new
def new
@card_rx = CardRx.new
end
# GET /card_rxes/1/edit
def edit
end
# POST /card_rxes or /card_rxes.json
def create
@card_rx = CardRx.new(card_rx_params)
respond_to do |format|
if @card_rx.save
format.html { redirect_to @card_rx, notice: "Card rx was successfully created." }
format.json { render :show, status: :created, location: @card_rx }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @card_rx.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /card_rxes/1 or /card_rxes/1.json
def update
respond_to do |format|
if @card_rx.update(card_rx_params)
format.html { redirect_to @card_rx, notice: "Card rx was successfully updated.", status: :see_other }
format.json { render :show, status: :ok, location: @card_rx }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: @card_rx.errors, status: :unprocessable_entity }
end
end
end
# DELETE /card_rxes/1 or /card_rxes/1.json
def destroy
@card_rx.destroy!
respond_to do |format|
format.html { redirect_to card_rxes_path, notice: "Card rx was successfully destroyed.", status: :see_other }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_card_rx
@card_rx = CardRx.find(params[:id])
end
# Only allow a list of trusted parameters through.
def card_rx_params
params.require(:card_rx).permit(:help_desk, :customer_service, :web_url)
end
end
+70
View File
@@ -0,0 +1,70 @@
class CarriersController < ApplicationController
before_action :set_carrier, only: %i[ show edit update destroy ]
# GET /carriers or /carriers.json
def index
@carriers = Carrier.all
end
# GET /carriers/1 or /carriers/1.json
def show
end
# GET /carriers/new
def new
@carrier = Carrier.new
end
# GET /carriers/1/edit
def edit
end
# POST /carriers or /carriers.json
def create
@carrier = Carrier.new(carrier_params)
respond_to do |format|
if @carrier.save
format.html { redirect_to @carrier, notice: "Carrier was successfully created." }
format.json { render :show, status: :created, location: @carrier }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @carrier.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /carriers/1 or /carriers/1.json
def update
respond_to do |format|
if @carrier.update(carrier_params)
format.html { redirect_to @carrier, notice: "Carrier was successfully updated.", status: :see_other }
format.json { render :show, status: :ok, location: @carrier }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: @carrier.errors, status: :unprocessable_entity }
end
end
end
# DELETE /carriers/1 or /carriers/1.json
def destroy
@carrier.destroy!
respond_to do |format|
format.html { redirect_to carriers_path, notice: "Carrier was successfully destroyed.", status: :see_other }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_carrier
@carrier = Carrier.find(params[:id])
end
# Only allow a list of trusted parameters through.
def carrier_params
params.require(:carrier).permit(:name)
end
end
-13
View File
@@ -1,13 +0,0 @@
class CommentsController < ApplicationController
before_action :set_article
def create
@article.comments.create! params.required(:comment).permit(:content)
redirect_to @article
end
private
def set_article
@article = Article.find(params[:article_id])
end
end
+4
View File
@@ -0,0 +1,4 @@
class DashboardController < ApplicationController
def index
end
end
@@ -1,257 +0,0 @@
class EmployerSetupController < ApplicationController
def index
@employer_setups = EmployerSetupProcess.all
end
def show
end
def new
@employer_setup = EmployerSetupProcess.new
@employer_setup.plans.build
@plan_templates = IdCardBenefitsTemplate.where.not(title: "BLANK")
render :new
end
def import
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
render :edit
else
@employer_setup = EmployerSetupProcess.new
@employer_setup.plans.build
render :new
end
end
def create
employer_setup_process_params = EmployerSetupProcess.permitted_params(params)
puts "---Params---"
puts employer_setup_process_params
# post_image_processing_params = process_logos(employer_setup_process_params)
@employer_setup = EmployerSetupProcess.new(employer_setup_process_params)
if @employer_setup.save
# update_logos_with_employer_setup_information()
redirect_to @employer_setup, notice: 'Employer Setup Process initiated'
else
@plan_templates = IdCardBenefitsTemplate.where.not(title: "BLANK")
render :new
end
end
def edit
@employer_setup = EmployerSetupProcess.find_by(slug: params[:id])
@plan_templates = IdCardBenefitsTemplate.where.not(title: "BLANK")
render :edit
# @resource = Resource.find(params[:id])
end
def update
@form = RegistrationForm.new(registration_params)
if params[:back_button]
@form.current_step = @form.previous_step
elsif params[:skip_newsletter]
@form.current_step = @form.next_step # Skip newsletter step
end
render :new
end
def destroy
# @resource = Resource.find(params[:id])
# @resource.destroy
# redirect_to resources_url, notice: 'Resource was successfully destroyed.'
end
private
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_setup.present?
logo_file.employer_setup_process = @employer_setup
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_exceptions_params
# params.require(:employer_setup_network_exceptions_form).permit(
# network_exceptions: [:network_logo, exceptions: [:type, :value]],
# )
# end
def form_for_step
step_name = @top_form.current_step
form_method = "EmployerSetup#{step_name.camelize}Form".constantize
# 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_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_exceptions: [:network_logo, exceptions: [:type, :value]],
# plans: permited_plans_keys,
# benefit_descs: benefit_sequence_keys
# )
# end
# def benefit_sequence_keys
# (1..14).map { |i| i.to_s.to_sym }
# end
# def permited_plans_keys
# benefit_sequence_keys.push(:plan_id)
# end
# def plans_params
# plans_keys = params[:plans]&.keys || []
# plans_keys.each_with_object({}) do |key, hash|
# if key == 'benefit_descs' || key.match?(/^plan_\d$/)
# hash[key.to_sym] = permited_plan_param_list
# end
# end
# end
# def permited_plan_param_list
# (1..14).map { |i| i.to_s.to_sym }.push(:plan_id)
# end
end
@@ -1,244 +0,0 @@
class EmployerSetupController < ApplicationController
def new
# session.delete(:employer_setup_data)
# session.clear()
# puts "Start"
# puts session[:employer_setup_data]
if session[:employer_setup_data].blank?
@process = EmployerSetupProcess.create(status: "form")
session[:employer_setup_data] = { "employer_setup_process_id" => @process.id }
end
puts "-S--------------------------------------"
puts session[:employer_setup_data]
# session[:employer_setup_data]['current_step'] = 'plans'
@top_form = EmployerSetupForm.new(session[:employer_setup_data])
if @top_form.current_step != 'summary'
@form = form_for_step
else
@form = @top_form
end
# case @top_form.current_step
# when 'general_information'
# @form = EmployerSetupGeneralInformationForm.new(session[:employer_setup_data]&.dig('general_information_data'))
# when 'plans'
# @form = EmployerSetupPlansForm.new(session[:employer_setup_data]&.dig('plans_data'))
# when 'network_exceptions'
# @form = EmployerSetupNetworkExceptionsForm.new(session[:employer_setup_data]&.dig('network_exceptions_data'))
# when 'summary'
# @form = @top_form
# end
render @top_form.current_step_view
end
def create
# puts session[:employer_setup_data]
@top_form = EmployerSetupForm.new(session[:employer_setup_data])
if @top_form.current_step != 'summary'
if process_step(@top_form.current_step)
session[:employer_setup_data]['current_step'] = @top_form.next_step
puts "---------------------------------------"
puts "pass"
puts "next - #{@top_form.next_step}"
puts session[:employer_setup_data]
puts "---------------------------------------"
redirect_to new_employer_setup_path
else
puts "fail"
render @top_form.current_step_view
end
else
if @top_form.save
session.delete(:employer_setup_data)
redirect_to root_path, notice: "Employer setup successfully!"
else
render @top_form.current_step_view
end
end
# case @top_form.current_step
# when 'general_information'
# @form = EmployerSetupGeneralInformationForm.new(general_information_params)
# if @form.valid?
# session[:employer_setup_data]['general_information_data'] = general_information_params
# session[:employer_setup_data]['current_step'] = @top_form.next_step
# redirect_to new_employer_setup_path
# else
# render @top_form.current_step_view
# end
# when 'plans'
# @form = EmployerSetupPlansForm.new(plans_params)
# if @form.valid?
# session[:employer_setup_data]['plans_data'] = plans_params
# session[:employer_setup_data]['current_step'] = @top_form.next_step
# redirect_to new_employer_setup_path
# else
# render @top_form.current_step_view
# end
# when 'network_exceptions'
# @form = EmployerSetupNetworkExceptionsForm.new(network_exceptions_params)
# if @form.valid?
# session[:employer_setup_data]['network_exceptions_data'] = network_exceptions_params
# session[:employer_setup_data]['current_step'] = @top_form.next_step
# redirect_to new_employer_setup_path
# else
# render @top_form.current_step_view
# end
# when 'summary'
# @form = EmployerSetupForm.new(session[:employer_setup_data])
# if @form.save
# session.delete(:employer_setup_data)
# redirect_to root_path, notice: "Employer setup successfully!"
# else
# render @top_form.current_step_view
# end
# end
end
def update
@form = RegistrationForm.new(registration_params)
if params[:back_button]
@form.current_step = @form.previous_step
elsif params[:skip_newsletter]
@form.current_step = @form.next_step # Skip newsletter step
end
render :new
end
private
# def general_information_params
# params.require(:employer_setup_general_information_form).permit(
# :name,
# :employer_logo,
# :group_number,
# :dental,
# :pl_plan_key,
# :effect_date,
# :number_of_plans,
# :network,
# :number_of_additional_network_logos
# )
# end
# def plans_params
# params.require(:employer_setup_plans_form).permit(
# plans: permited_plans_keys,
# benefit_descs: benefit_sequence_keys
# )
# end
# def network_exceptions_params
# params.require(:employer_setup_network_exceptions_form).permit(
# network_exceptions: [:network_logo, exceptions: [:type, :value]],
# )
# end
def 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_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_exceptions: [:network_logo, exceptions: [:type, :value]],
# plans: permited_plans_keys,
# benefit_descs: benefit_sequence_keys
# )
# end
# def benefit_sequence_keys
# (1..14).map { |i| i.to_s.to_sym }
# end
# def permited_plans_keys
# benefit_sequence_keys.push(:plan_id)
# end
# def plans_params
# plans_keys = params[:plans]&.keys || []
# plans_keys.each_with_object({}) do |key, hash|
# if key == 'benefit_descs' || key.match?(/^plan_\d$/)
# hash[key.to_sym] = permited_plan_param_list
# end
# end
# end
# def permited_plan_param_list
# (1..14).map { |i| i.to_s.to_sym }.push(:plan_id)
# end
end
@@ -1,109 +0,0 @@
class EmployerSetupController < ApplicationController
def new
@employer_data = session[:employer_data] || {}
# @id_card_templates = IdCardTemplate.where.not(title: "BLANK")
# @id_card_template_benefits = IdCardTemplate.find_by(title: "BLANK").id_card_template_benefits.sort_by(&:sequence)
end
def create_employer
@employer_data = {employer: {}}
@employer_data[:employer].merge!(params.require(:employer).permit(
:name,
:group_number,
:pl_plan_key,
:effective_date
))
@employer_data[:employer].merge!(params.permit(:number_of_plans))
session[:employer_data] = @employer_data
puts session[:employer_data]
redirect_to action: :plans
end
def plans
@employer_data = session[:employer_data] || {}
@id_card_templates = IdCardBenefitsTemplate.where.not(title: "BLANK")
@id_card_template_benefits = IdCardBenefitsTemplate.find_by(title: "BLANK").id_card_benefits.sort_by(&:sequence)
end
def create_plans
@employer_data = session[:employer_data] || {}
@employer_data.merge!(params.require(:plans).permit(plans_params))
session[:employer_data] = @employer_data
redirect_to action: :networks
end
def networks
@employer_data = session[:employer_data] || {}
end
def create_provider_networks
@employer_data = session[:employer_data] || {}
@employer_data.merge!(params.require(:plans).permit(plans_params))
session[:employer_data] = @employer_data
redirect_to action: :networks
end
def process_bad_name
@final_data = session[:employer_data]
# Vhcs::HlPlanCode.create(
# group_number: @final_data['employer']['name'],
# medical_number: @final_data['employer']['group_number'],
# dental_number: ' ',
# plan_key: @final_data['employer']['pl_plan_key'],
# effective_date: @final_data['employer']['effective_date']
# )
# default = Vhcs::HLRXCrosRef.find_by(pl_plan_key: 52)
# Vhcs::HLRXCrosRef.create(
# group_no: @final_data['employer']['group_number'],
# rx_group_id: @final_data['employer']['group_number'],
# help_desk: default.help_desk,
# customer_service: default.customer_service,
# web_url: default.web_url,
# pl_plan_key: @final_data['employer']['pl_plan_key']
# )
# plans_data = @final_data['plans']
# benefit_descs = plans_data.delete('benefit_descs')
# plans_data.each do |key, value|
# plan_id = value.delete('plan_id')
# value.each do |key2, value2|
# Vhcs::HLEgglestonCardBenefit.create(
# plan_id: plan_id,
# benefit_desc: benefit_descs[key2],
# benefit: value2,
# sequence: key2,
# plan_key: @final_data['employer']['pl_plan_key']
# )
# end
# end
# Create or update your model with @final_data
# Clear the session data after successful save
session[:employer_data] = nil
# Redirect to a success page
end
private
def plans_params
plans_keys = params[:plans]&.keys || []
plans_keys.each_with_object({}) do |key, hash|
if key == 'benefit_descs' || key.match?(/^plan_\d$/)
hash[key.to_sym] = permited_plan_param_list
end
end
end
def permited_plan_param_list
(1..14).map { |i| i.to_s.to_sym }.push(:plan_id)
end
end
@@ -1,89 +0,0 @@
class EmployerSetupController < ApplicationController
def new
# session.delete(:employer_setup_data)
@form = EmployerSetupForm.new(session[:employer_setup_data])
if @form.current_step == "plans"
@id_card_templates = IdCardBenefitsTemplate.where.not(title: "BLANK")
@id_card_template_benefits = IdCardBenefitsTemplate.find_by(title: "BLANK").id_card_benefits.sort_by(&:sequence)
end
puts session[:employer_setup_data]
render "employer_setup/#{@form.current_step}" # Renders the view for the current step
end
def create
filtered_params = employer_setup_params.except(:validation_context)
@form = EmployerSetupForm.new(filtered_params)
if @form.current_step == "general" && @form.valid?(:general_info)
# @form.current_step = "plans"
@form.current_step = "networks" # TESTING, Change Back
session[:employer_setup_data] = @form.attributes.slice("current_step", "name", "employer_logo", "group_number", "pl_plan_key", "effect_date", "number_of_plans", "network", "number_of_additional_network_logos")
redirect_to new_employer_setup_path # Redirect to the next step
elsif @form.current_step == "plans" && @form.valid?(:plan_info)
if @form.number_of_additional_network_logos == 0
next_step = "summary"
else
next_step = "networks"
end
@form.current_step = next_step
session[:employer_setup_data].merge!(@form.attributes.slice("current_step", "plans", "benefit_descs"))
redirect_to new_employer_setup_path
# @form = UserOnboardingForm.new(session[:employer_setup_data]) # Re-initialize with all data
elsif @form.current_step == "networks" && @form.valid?(:network_info)
@form.current_step = "summary"
session[:employer_setup_data].merge!(@form.attributes.slice("current_step", "network_exceptions"))
redirect_to new_employer_setup_path
elsif @form.current_step == "summary"
puts @form.attributes
if @form.save
session.delete(:employer_setup_data) # Clear session data after successful save
redirect_to root_path, notice: "Employer setup successfully!"
else
render "employer_setup/summary" # Render step two again with errors
end
else
render "employer_setup/#{@form.current_step}" # Render the current step again with errors
end
end
private
def employer_setup_params
params.require(:employer_setup_form).permit(
:current_step,
:name,
:employer_logo,
:group_number,
:pl_plan_key,
:effect_date,
:number_of_plans,
:network,
:number_of_additional_network_logos,
network_exceptions: [:network_logo, exceptions: [:type, :value]],
plans: permited_plans_keys,
benefit_descs: benefit_sequence_keys
)
end
def benefit_sequence_keys
(1..14).map { |i| i.to_s.to_sym }
end
def permited_plans_keys
benefit_sequence_keys.push(:plan_id)
end
def plans_params
plans_keys = params[:plans]&.keys || []
plans_keys.each_with_object({}) do |key, hash|
if key == 'benefit_descs' || key.match?(/^plan_\d$/)
hash[key.to_sym] = permited_plan_param_list
end
end
end
def permited_plan_param_list
(1..14).map { |i| i.to_s.to_sym }.push(:plan_id)
end
end
+44 -212
View File
@@ -1,6 +1,13 @@
class EmployersController < ApplicationController class EmployersController < ApplicationController
# View Methods
def index def index
@employers = Employer.all @uninitialized = Employer.in_automation_initilization
@with_active_id_card_setup = Employer.active
current_group_numbers = @with_active_id_card_setup.pluck(:group_number)
valid_group_numbers = ["62210","61986","42018","41283","0230643","43190","0230642","0230644","0230646","0233955","600102","0249127","0257902","0257947","600112","600114","0261611","600117","0261684","0261685","0261826","600121","0265450","600123","0267470","0268540","0268599"]
@beta_unassigned_group_numbers = valid_group_numbers - current_group_numbers
@deactivated = Employer.deactivated
end end
def show def show
@@ -9,47 +16,25 @@ class EmployersController < ApplicationController
def new def new
@employer = Employer.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 render :new
end end
def create def create
employer_params = Employer.permitted_params(params) employer_params = Employer.permitted_params(params)
puts "---Params---"
puts employer_params
# post_image_processing_params = process_logos(employer_setup_process_params)
@employer = Employer.new(employer_params) @employer = Employer.new(employer_params)
if @employer.save if @employer.save
# update_logos_with_employer_setup_information()
redirect_to employer_path(@employer.slug), notice: 'Employer Saved' redirect_to employer_path(@employer.slug), notice: 'Employer Saved'
else else
@plan_templates = IdCardBenefitsTemplate.where.not(title: "BLANK") render :new, status: :unprocessable_entity
render :new
end end
end end
def edit def edit
@employer = Employer.find_by(slug: params[:id]) @employer = Employer.find_by(slug: params[:id])
@plan_templates = IdCardBenefitsTemplate.where.not(title: "BLANK")
render :edit render :edit
# @resource = Resource.find(params[:id])
end end
def update def update
puts "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
employer_params = Employer.permitted_params(params) employer_params = Employer.permitted_params(params)
@employer = Employer.find(params[:id]) @employer = Employer.find(params[:id])
@@ -64,196 +49,43 @@ class EmployersController < ApplicationController
end end
def destroy def destroy
# @resource = Resource.find(params[:id]) @employer = Employer.find(params[:id])
# @resource.destroy @employer.destroy
# redirect_to resources_url, notice: 'Resource was successfully destroyed.' redirect_to employers_path, notice: "#{@employer.name} was successfully deleted."
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 beta_automation_simulation
BetaAutomationSimulationService.new().call
redirect_to employers_path
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 end
private private
# 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_exceptions_params
# params.require(:employer_setup_network_exceptions_form).permit(
# network_exceptions: [:network_logo, exceptions: [:type, :value]],
# )
# end
# def form_for_step
# step_name = @top_form.current_step
# form_method = "EmployerSetup#{step_name.camelize}Form".constantize
# # 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_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_exceptions: [:network_logo, exceptions: [:type, :value]],
# plans: permited_plans_keys,
# benefit_descs: benefit_sequence_keys
# )
# end
# def benefit_sequence_keys
# (1..14).map { |i| i.to_s.to_sym }
# end
# def permited_plans_keys
# benefit_sequence_keys.push(:plan_id)
# end
# def plans_params
# plans_keys = params[:plans]&.keys || []
# plans_keys.each_with_object({}) do |key, hash|
# if key == 'benefit_descs' || key.match?(/^plan_\d$/)
# hash[key.to_sym] = permited_plan_param_list
# end
# end
# end
# def permited_plan_param_list
# (1..14).map { |i| i.to_s.to_sym }.push(:plan_id)
# end
end end
@@ -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"]
employer_id = logo_params["employer_id"]
employer = Employer.find(employer_id)
setup = employer.id_card_setup
if setup.present? && 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)
employer_logo = IdCard::EmployerLogo.find_or_create_by(filename: filename, setup_id: setup.id)
employer_logo.update(image_data: binary_data)
render json: employer_logo, 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, :employer_id)
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
+133
View File
@@ -0,0 +1,133 @@
module IdCard
class PrintController < ApplicationController
# View Methods
def index
@employer_setups = IdCard::Setup.active.to_a
@queue_members = IdCardQueueService::GetQueuedMembers.new().call
update_missing_members(@queue_members)
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
# @queue_members.delete_if { |em| ["2", "19", "16", "54"].include?(em[:pl_plan_key])}
# @queue_members.push({pl_plan_key: "54", member_keys: [383840]})
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
# @queue_members.first[:member_keys].delete(379590) && @queue_members.first[:member_keys].push(379610)
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
employer_id = params[:id]
@employer = Employer.find(employer_id)
sample_cards_pdf = IdCardPrinterService::SampleCardsGenerator.new(@employer.id).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 update_missing_members(queued_employer_members)
queued_employer_members.each do |queued_employer|
existing_members = Member.where(pb_entity_key: queued_employer[:member_keys]).pluck(:pb_entity_key)
missing_members = queued_employer[:member_keys] - existing_members
missing_members.each do |pb_entity_key|
AutomationService::MemberUpdate.new(queued_employer[:pl_plan_key], pb_entity_key).call
end
end
end
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
+107
View File
@@ -0,0 +1,107 @@
module IdCard
class SetupController < ApplicationController
before_action :set_employer_and_setup
# View Methods
def index
if @setup.provider_section.present? && !@setup.provider_section.default
employer_custom_options = @setup.provider_section
else
employer_custom_options = IdCard::ProviderSection.new(title: "#{@employer.name} Custom")
end
@provider_options = (IdCard::ProviderSection.where(default: true) + [employer_custom_options])
.compact.uniq.map { |option| [option.display_title, option.id || "99"] }
@rx_options = IdCard::RxSection.where.not(title: nil)
@rx_default = IdCard::RxSection.find_by(title: "FairosRx")
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"
if @setup.provider_section.present? && !@setup.provider_section.default
employer_custom_options = @setup.provider_section
else
employer_custom_options = IdCard::ProviderSection.new(title: "#{@employer.name} Custom")
end
@provider_options = (IdCard::ProviderSection.where(default: true) + [employer_custom_options])
.compact.uniq.map { |option| [option.display_title, option.id || "99"] }
@rx_options = IdCard::RxSection.all
@rx_default = IdCard::RxSection.find_by(title: "FairosRx")
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"
@plan_templates = IdCard::Plan.templates
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
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
end
end
@@ -1,89 +0,0 @@
class IdCardBenefitsTemplatesController < ApplicationController
skip_before_action :verify_authenticity_token
def new_id_card_template
@id_card_templates = IdCardTemplate.where.not(title: "BLANK")
@id_card_template_benefits = IdCardTemplate.find_by(title: "BLANK").id_card_template_benefits.sort_by(&:sequence)
end
def create_id_card_template
@id_card_template = IdCardTemplate.create(title: params[:title])
params[:benefits].each do |key, value|
IdCardTemplateBenefit.create(
sequence: key,
benefit_desc: value["desc"],
benefit: value["value"],
id_card_template: @id_card_template
)
end
respond_to do |format|
if @id_card_template.save && @id_card_template.id_card_template_benefits.length == 14
format.html { redirect_to '/dev_tools/new_id_card_setup', notice: "Template was successfully created." }
# format.json { render :show, status: :created, location: @employer }
else
format.html { render :new_id_card_template, status: :unprocessable_entity }
# format.json { render json: @employer.errors, status: :unprocessable_entity }
end
end
end
def new_id_card_setup
@id_card_templates = IdCardTemplate.where.not(title: "BLANK")
@id_card_template_benefits = IdCardTemplate.find_by(title: "BLANK").id_card_template_benefits
end
def get_template_benefits
@id_card_benefits = IdCardBenefitsTemplate.find(params[:id]).id_card_benefits
render json: @id_card_benefits.as_json
end
def create_id_card_setup
employer_general = params['general']
hl_plan_code = Vhcs::HlPlanCode.new(
group_number: employer_general['group_number'],
medical_number: employer_general['group_number'],
dental_number: '',
plan_key: employer_general['pl_plan_key'],
effect_date: employer_general['effect_date']
)
# Replace fairos_info with template like for benefits
fairos_info = Vhcs::HLRXCrosRef.where(pl_plan_key: 52).first
hlrx_cros_ref = Vhcs::HLRXCrosRef.new(
group_no: employer_general['group_number'],
rx_group_id: employer_general['group_number'],
help_desk: fairos_info.help_desk,
customer_service: fairos_info.customer_service,
web_url: fairos_info.web_url,
pl_plan_key: employer_general['pl_plan_key']
)
number_of_plans = params[:number_of_plans].to_i
number_of_plans.each do |i|
value['benefits'].each do |ben_key, ben_value|
Vhcs::HLEgglestonCardBenefit.create(
plan_id: value['plan_id'],
benefit_desc: ben_value["desc"],
benefit: ben_value["value"],
sequence: ben_key,
plan_key: employer_general['pl_plan_key']
)
end
end
respond_to do |format|
if hl_plan_code.save && hlrx_cros_ref.save
format.html { redirect_to '/dev_tools/new_id_card_setup', notice: "Card setup was successfully created." }
# format.json { render :show, status: :created, location: @employer }
else
format.html { render :new_id_card_setup, status: :unprocessable_entity }
# format.json { render json: @employer.errors, status: :unprocessable_entity }
end
end
end
end
@@ -0,0 +1,70 @@
class ProviderGroupsController < ApplicationController
before_action :set_provider_group, only: %i[ show edit update destroy ]
# GET /provider_groups or /provider_groups.json
def index
@provider_groups = ProviderGroup.all
end
# GET /provider_groups/1 or /provider_groups/1.json
def show
end
# GET /provider_groups/new
def new
@provider_group = ProviderGroup.new
end
# GET /provider_groups/1/edit
def edit
end
# POST /provider_groups or /provider_groups.json
def create
@provider_group = ProviderGroup.new(provider_group_params)
respond_to do |format|
if @provider_group.save
format.html { redirect_to @provider_group, notice: "Provider group was successfully created." }
format.json { render :show, status: :created, location: @provider_group }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @provider_group.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /provider_groups/1 or /provider_groups/1.json
def update
respond_to do |format|
if @provider_group.update(provider_group_params)
format.html { redirect_to @provider_group, notice: "Provider group was successfully updated.", status: :see_other }
format.json { render :show, status: :ok, location: @provider_group }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: @provider_group.errors, status: :unprocessable_entity }
end
end
end
# DELETE /provider_groups/1 or /provider_groups/1.json
def destroy
@provider_group.destroy!
respond_to do |format|
format.html { redirect_to provider_groups_path, notice: "Provider group was successfully destroyed.", status: :see_other }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_provider_group
@provider_group = ProviderGroup.find(params[:id])
end
# Only allow a list of trusted parameters through.
def provider_group_params
params.require(:provider_group).permit(:name)
end
end
+70
View File
@@ -0,0 +1,70 @@
class ProvidersController < ApplicationController
before_action :set_provider, only: %i[ show edit update destroy ]
# GET /providers or /providers.json
def index
@providers = Provider.all
end
# GET /providers/1 or /providers/1.json
def show
end
# GET /providers/new
def new
@provider = Provider.new
end
# GET /providers/1/edit
def edit
end
# POST /providers or /providers.json
def create
@provider = Provider.new(provider_params)
respond_to do |format|
if @provider.save
format.html { redirect_to @provider, notice: "Provider was successfully created." }
format.json { render :show, status: :created, location: @provider }
else
format.html { render :new, status: :unprocessable_entity }
format.json { render json: @provider.errors, status: :unprocessable_entity }
end
end
end
# PATCH/PUT /providers/1 or /providers/1.json
def update
respond_to do |format|
if @provider.update(provider_params)
format.html { redirect_to @provider, notice: "Provider was successfully updated.", status: :see_other }
format.json { render :show, status: :ok, location: @provider }
else
format.html { render :edit, status: :unprocessable_entity }
format.json { render json: @provider.errors, status: :unprocessable_entity }
end
end
end
# DELETE /providers/1 or /providers/1.json
def destroy
@provider.destroy!
respond_to do |format|
format.html { redirect_to providers_path, notice: "Provider was successfully destroyed.", status: :see_other }
format.json { head :no_content }
end
end
private
# Use callbacks to share common setup or constraints between actions.
def set_provider
@provider = Provider.find(params[:id])
end
# Only allow a list of trusted parameters through.
def provider_params
params.fetch(:provider, {})
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
-4
View File
@@ -1,4 +0,0 @@
class WelcomeController < ApplicationController
def index
end
end
+12 -10
View File
@@ -3,9 +3,9 @@ class TailwindFormBuilder < ActionView::Helpers::FormBuilder
# leans on the FormBuilder class_attribute `field_helpers` # leans on the FormBuilder class_attribute `field_helpers`
# you'll want to add a method for each of the specific helpers listed here if you want to style them # you'll want to add a method for each of the specific helpers listed here if you want to style them
TEXT_FIELD_STYLE = "bg-gray-200 rounded py-2 px-4 text-bluetang font-semibold leading-tight focus:outline-none focus:bg-white".freeze TEXT_FIELD_STYLE = "flex bg-gray-200 rounded py-2 px-4 text-bluetang font-semibold leading-tight focus:outline-none focus:bg-white border border-platinum".freeze
SELECT_FIELD_STYLE = "block bg-gray-200 text-gray-700 py-2 px-4 rounded leading-tight focus:outline-none focus:bg-white".freeze SELECT_FIELD_STYLE = "block bg-gray-200 text-bluetang py-2 px-4 font-semibold rounded leading-tight focus:outline-none focus:bg-white border border-platinum".freeze
SUBMIT_BUTTON_STYLE = "cursor-pointer shadow bg-bronze focus:shadow-outline focus:outline-none text-white font-bold py-2 px-4 rounded hover:bg-copper".freeze SUBMIT_BUTTON_STYLE = "cursor-pointer font-bold text-lg text-platinum hover:text-bronze bg-cobalt-vivid hover:bg-deepcove border-2 border-cobalt-vivid py-2 px-4 rounded".freeze
text_field_helpers.each do |field_method| text_field_helpers.each do |field_method|
class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1 class_eval <<-RUBY_EVAL, __FILE__, __LINE__ + 1
@@ -48,6 +48,7 @@ class TailwindFormBuilder < ActionView::Helpers::FormBuilder
custom_opts, opts = partition_custom_opts(options) custom_opts, opts = partition_custom_opts(options)
classes = apply_style_classes(TEXT_FIELD_STYLE, custom_opts, object_method) classes = apply_style_classes(TEXT_FIELD_STYLE, custom_opts, object_method)
puts "classes: #{classes}"
field = send(field_method, object_method, { field = send(field_method, object_method, {
class: classes, class: classes,
@@ -63,18 +64,18 @@ class TailwindFormBuilder < ActionView::Helpers::FormBuilder
label = tailwind_label(object_method, label_options, field_options) label = tailwind_label(object_method, label_options, field_options)
error_label = error_label(object_method, field_options) error_label = error_label(object_method, field_options)
@template.content_tag("div", label + error_label, {class: "flex flex-col items-start"}) @template.content_tag("div", label + error_label, {class: "flex justify-between"})
end end
def tailwind_label(object_method, label_options, field_options) def tailwind_label(object_method, label_options, field_options)
text, label_opts = if label_options.present? text, label_opts = if label_options.present?
[label_options[:text], label_options.except(:text)] [label_options[:text], label_options.except(:text)]
else else
[nil, {}] [object_method.to_s.titleize, {}]
end end
label_classes = label_opts[:class] || "block text-platinum font-bold md:text-right mb-1 md:mb-0 pr-4" label_classes = label_opts[:class] || "block shrink-0 text-platinum font-bold md:text-right mb-1 md:mb-0 pr-4"
label_classes += " text-yellow-800 dark:text-yellow-400" if field_options[:disabled] label_classes += " dark:text-brightlava" if field_options[:disabled]
label(object_method, text, { label(object_method, text, {
class: label_classes class: label_classes
}.merge(label_opts.except(:class))) }.merge(label_opts.except(:class)))
@@ -83,15 +84,16 @@ class TailwindFormBuilder < ActionView::Helpers::FormBuilder
def error_label(object_method, options) def error_label(object_method, options)
if errors_for(object_method).present? if errors_for(object_method).present?
error_message = @object.errors[object_method].collect(&:titleize).join(", ") error_message = @object.errors[object_method].collect(&:titleize).join(", ")
tailwind_label(object_method, {text: error_message, class: " font-bold text-red-500"}, options) tailwind_label(object_method, {text: error_message, class: " font-bold text-right text-bronze"}, options)
end end
end end
def border_color_classes(object_method) def border_color_classes(object_method)
if errors_for(object_method).present? if errors_for(object_method).present?
" border-2 border-red-400 focus:border-rose-200" " border-4 dark:border-bronze focus:border-atmosphere"
else else
" border border-platinum focus:border-yellow-700" ""
# " border border-platinum focus:border-yellow-700"
end end
end end
-85
View File
@@ -1,85 +0,0 @@
class EmployerSetupForm
include ActiveModel::Model
include ActiveModel::Attributes
FIRST_STEP = "general_information"
attribute :current_step, :string, default: FIRST_STEP
attribute :pl_plan_key, :string
attribute :employer_setup_process_id, :integer
def initialize(params = {})
# if params.present?
# params = permitted_params(params)
# end
# @current_step = params["current_step"]
# @employer_setup_process_id = params["employer_setup_process_id"]
super(params)
unless self.steps.first == FIRST_STEP
raise StepMisalignmentError, "FIRST_STEP does not match first entry in steps"
end
# @general_information_data = EmployerSetupGeneralInformationForm.new(attributes[:general_information_data])
# @plans_data = EmployerSetupPlansForm.new(attributes[:plans_data])
# @network_exceptions_data = EmployerSetupNetworkExceptionsForm.new(attributes[:network_exceptions_data])
end
# def self.form_session_init
# {
# general_information_data: {},
# plans_data: {},
# network_exceptions_data: {}
# }
# end
# def steps
# %w[general_information plans network_exceptions summary]
# end
def steps
%w[general_information plans network_exceptions summary]
end
def current_step_view
"employer_setup/#{self.current_step}"
end
def next_step
index = steps.index(current_step)
if index && index < steps.length - 1
steps[index + 1]
end
end
def previous_step
index = steps.index(current_step)
steps[index - 1] if index && index > 0
end
def permitted_params(params)
params.permit(
:pl_plan_key,
:current_step
)
end
def self.permitted_params
[
:pl_plan_key,
:current_step
]
end
def save
if valid?
process = EmployerSetupProcess.find(@employer_setup_process_id)
process.update(
status: "entered"
)
true
else
false
end
end
end
@@ -1,62 +0,0 @@
class EmployerSetupForm
include ActiveModel::Model
include ActiveModel::Attributes
attribute :current_step, :string, default: "general"
attribute :name, :string
attribute :employer_logo
attribute :group_number, :string
attribute :pl_plan_key, :string
attribute :effect_date, :string
attribute :number_of_plans, :integer
attribute :network, :string
attribute :number_of_additional_network_logos, :integer
attribute :plans, array: true, default: -> { [] }
# attribute :benefit_descs, :hash, default: -> { {} }
attribute :network_exceptions, array: true, default: -> { [] }
attr_accessor :benefit_descs
# Define validations based on the current step
with_options on: :general_info do
validates :name, presence: true
validates :employer_logo, presence: true
validates :group_number, presence: true
validates :pl_plan_key, presence: true
validates :effect_date, presence: true
validates :number_of_plans, presence: true
validates :network, presence: true
# validates :number_of_additional_network_logos, presence: true if network = "cigna+"
end
with_options on: :plan_info do
validates :plans, presence: true
# validates :benefit_descs, presence: true
end
with_options on: :network_info do
# validates :network_exceptions, presence: true if number_of_additional_network_logos > 0
end
# def initialize(params = {})
# super(params)
# # Ensure the attribute is a hash after initialization
# @benefit_descs = params[:benefit_descs].to_h if params[:benefit_descs]
# end
def benefit_descs
@benefit_descs ||= {}
end
def save
# Implement logic to save data to models after all steps are complete
# For example, create a User record with the collected data
if valid? && step == total_steps
# User.create!(name: name, email: email, password: password)
true
else
false
end
end
end
@@ -1,130 +0,0 @@
class EmployerSetupGeneralInformationForm
include ActiveModel::Model
include ActiveModel::Attributes
attribute :name, :string
attribute :employer_logo
attribute :group_number, :string
attribute :dental, :boolean, default: false
attribute :pl_plan_key, :string
attribute :effective_date, :string
# attribute :number_of_plans, :integer
attribute :network, :string
# attribute :number_of_additional_network_logos, :integer
attr_accessor :employer_setup_process_id
validates :name, presence: true
validates :employer_logo, presence: true
validates :group_number, presence: true
validates :effective_date, presence: true
# validates :number_of_plans, presence: true
validates :network, presence: true
# validates :number_of_additional_network_logos, presence: true if network = "cigna+"
# def initialize(attributes = {})
# if attributes
# permitted_attributes = form_strong_params(attributes)
# super(permitted_attributes)
# end
def initialize(employer_setup_process_id, params = {})
@employer_setup_process_id = employer_setup_process_id
if params.present?
form_params = permitted_params(params)
super(form_params)
else
super(params)
load_from_process
end
end
def load_from_process
process = EmployerSetupProcess.find(@employer_setup_process_id)
self.name = process.employer_name
# self.employer_logo = process.
self.group_number = process.group_number
self.dental = false
self.pl_plan_key = process.pl_plan_key
self.effective_date = process.effective_date
self.network = process.network_provider
end
def permitted_params(params)
params.require(:employer_setup_general_information_form).permit(
:name,
:employer_logo,
:group_number,
:dental,
:pl_plan_key,
:effective_date,
:number_of_plans,
:network,
:number_of_additional_network_logos
)
end
def save
# Implement logic to save data to models after all steps are complete
# For example, create a User record with the collected data
if valid?
process = EmployerSetupProcess.find(@employer_setup_process_id)
process.update(
employer_name: name,
group_number: group_number,
pl_plan_key: pl_plan_key,
effective_date: effective_date,
network_provider: network
)
# hl_plan_code = Vhcs::HlPlanCode.create!(
# group_number: group_number,
# medical_number: group_number,
# dental_number: '',
# plan_key: pl_plan_key,
# effect_date: effective_date
# )
# # Replace fairos_info with template like for benefits
# fairos_info = Vhcs::HlrxCrosRef.where(pl_plan_key: 52).first
# hlrx_cros_ref = Vhcs::HlrxCrosRef.create!(
# group_no: group_number,
# rx_group_id: group_number,
# help_desk: fairos_info.help_desk,
# customer_service: fairos_info.customer_service,
# web_url: fairos_info.web_url,
# pl_plan_key: pl_plan_key
# )
# web_employer = BrittonWeb::Employers.create!(
# name: name,
# pl_plan_key: pl_plan_key,
# dental_plan: dental,
# single_card_template: 'FairosRxIDCard',
# logo: employer_logo.original_filename
# )
# default_network_logo =
# case
# when network.include?("cig")
# "CignaLogo.png"
# when network.include?("med")
# "Logo_MC_PMS.png"
# else
# "CignaLogo.png"
# end
# BrittonWeb::NetworkLogos.create!(
# employer_id: web_employer.id,
# net_logo: default_network_logo,
# default: true
# )
true
else
false
end
end
end
@@ -1,107 +0,0 @@
class EmployerSetupNetworkExceptionsForm
include ActiveModel::Model
include ActiveModel::Attributes
Network_exception = Struct.new(:network_logo, :exceptions)
attribute :network_exceptions, :array_of_items, default: -> { [] }
attribute :pl_plan_key, :string
attr_accessor :employer_setup_process_id
# validates :network_exceptions, presence: true if number_of_additional_network_logos > 0
def initialize(employer_setup_process_id, params = {})
@employer_setup_process_id = employer_setup_process_id
if params.present?
form_params = permitted_params(params)
super(form_params)
else
super(params)
end
end
def permitted_params(params)
params.require(:employer_setup_network_exceptions_form).permit(
network_exceptions: [
:network_logo,
exceptions: [
:type,
:value
]
]
)
end
# def self.permitted_params
# [
# network_exceptions: [
# :network_logo,
# exceptions: [
# :type,
# :value
# ]
# ]
# ]
# end
def pull_from_employer_setup_form(attributes = {})
if attributes['pl_plan_key']
self.pl_plan_key = attributes['pl_plan_key']
end
if attributes['number_of_additional_network_logos']
self.number_of_additional_network_logos = attributes['number_of_additional_network_logos']
end
end
def process_for_save(network_exceptions)
ne_array = []
network_exceptions.first.each do |ne|
processed_ne = ne.last
exceptions_array = []
processed_ne['exceptions'].each do |e|
exceptions_array.push(e.last)
end
processed_ne['exceptions'] = exceptions_array
ne_array.push(processed_ne)
end
ne_array
end
def save
# Implement logic to save data to models after all steps are complete
# For example, create a User record with the collected data
if valid?
process = EmployerSetupProcess.find(@employer_setup_process_id)
# employer = BrittonWeb::Employers.find_by(pl_plan_key: pl_plan_key)
if network_exceptions
network_exceptions_data = process_for_save(network_exceptions)
end
# network_exceptions_data.each do |ne|
# ne['exceptions'].each do |ex|
# BrittonWeb::NetworkLogos.create!(
# employer_id: employer.id,
# net_logo: ne['network_logo'].original_filename,
# exception_type: ex['type'].downcase,
# exception_value: ex['value'],
# default: false
# )
# end
# end
true
else
false
end
end
end
class NetworkException
include ActiveModel::Model
include ActiveModel::Attributes
attribute :network_logo
attribute :exceptions, array: true, default: -> { [] }
end
-186
View File
@@ -1,186 +0,0 @@
class EmployerSetupPlansForm
include ActiveModel::Model
include ActiveModel::Attributes
PLAN_COLORS = ['atmosphere', 'verdigris', 'bluemana', 'cobalt']
attribute :plans, array: true, default: -> { [Plan.new] }
attribute :pl_plan_key, :string
attribute :benefit_descs, hash: true, default: -> { Plan.new }
attr_accessor :plan_templates
attr_accessor :benefits_template
attr_accessor :employer_setup_process_id
validates :plans, presence: true
validates :benefit_descs, presence: true
def initialize(employer_setup_process_id, params = {})
@employer_setup_process_id = employer_setup_process_id
if params.present?
form_params = permitted_params(params)
super(form_params)
else
super(params)
process_plans = EmployerSetupProcess.find(@employer_setup_process_id).plans
if process_plans.present?
self.plans = process_plans
end
end
@plan_templates = IdCardBenefitsTemplate.where.not(title: "BLANK")
@benefits_template = IdCardBenefitsTemplate.find_by(title: "BLANK").id_card_benefits.sort_by(&:sequence)
# if attributes.present? && attributes[:plans].present?
# self.plans = Array(attributes[:plans])
# else
# self.plans = [new_plan]
# end
end
# def plans_attributes=(attributes)
# self.plans = attributes.values.map { |plan_attrs| Plan.new(plan_attrs) }
# end
def persisted?
false
end
# The core method to initialize the array with a single blank item.
def ensure_one_plan_exists
if plans.empty?
self.plans << PlanForm.new
self.plans << PlanForm.new
end
end
def bulild_descs_plan
self.benefit_descs = IdCardBenefitsTemplate.find_by(title: "BLANK").id_card_benefits.sort_by(&:sequence)
end
def self.new_plan
plan = {}
self.permited_plans_keys.each do |key|
plan[key] = ""
end
plan
end
def process_params(employer_setup_process_id)
process = EmployerSetupProcess.find(employer_setup_process_id)
process.plans
end
def permitted_params(params)
params.require(:employer_setup_plans_form).permit(
:pl_plan_key,
plans: self.permited_plans_keys,
benefit_descs: self.permited_plans_keys
)
end
def pull_from_employer_setup_form(attributes = {})
if attributes['pl_plan_key']
self.pl_plan_key = attributes['pl_plan_key']
end
if attributes['number_of_plans']
self.number_of_plans = attributes['number_of_plans']
end
end
# def form_strong_params(attributes)
# attributes.require(:employer_setup_plans_form).permit(
# plans: permited_plans_keys,
# benefit_descs: benefit_sequence_keys
# )
# end
def self.permited_plans_keys
(1..14).map { |i| "benefit_#{i}".to_sym }.push(:plan_id)
end
def permited_plans_keys
(1..14).map { |i| "benefit_#{i}".to_sym }.push(:plan_id, :id)
end
def save
# Implement logic to save data to models after all steps are complete
# For example, create a User record with the collected data
if valid?
process = EmployerSetupProcess.find(@employer_setup_process_id)
# process.plans.update(plans: plans)
planss = Array.wrap(plans)
plans.each_with_index do |plan, i|
plan_info = plan.last
plan_id = plan_info[:plan_id].present? ? plan_info[:plan_id].to_i : "temp #{i}"
plan_info.delete(:plan_id)
new_plan = process.plans.create(plan_id: plan_id)
plan_info.each do |key, value|
sequence = key.delete_prefix("benefit_").to_i
benefit = new_plan.plan_benefits.find_by(sequence: sequence)
benefit.update(
benefit: value
)
# Vhcs::HlEgglestonCardBenefit.create(
# plan_id: plan_id,
# benefit_desc: benefit_descs["#{key}"],
# benefit: value,
# sequence: sequence,
# plan_key: pl_plan_key
# )
end
end
# plans.each do |plan|
# plan_info = plan.last
# plan_id = plan_info.delete(:plan_id).to_i
# plan_info.each do |key, value|
# sequence = key.delete_prefix("benefit_").to_i
# Vhcs::HlEgglestonCardBenefit.create(
# plan_id: plan_id,
# benefit_desc: benefit_descs["#{key}"],
# benefit: value,
# sequence: sequence,
# plan_key: pl_plan_key
# )
# end
# end
true
else
false
end
end
end
class PlanForm
include ActiveModel::Model
include ActiveModel::Attributes
attribute :plan_id, :string
def initialize(attributes = {})
self.generate_attributes(14, "benefit_")
super(attributes)
end
def persisted?
false
end
def generate_attributes(count, prefix)
count.times do |i|
# attr_accessor :"#{prefix}#{i + 1}"
self.class.attribute "#{prefix}#{i + 1}".to_sym, :string
end
end
end
# dynamic_attribute_names.each do |attr_name|
# # Define each attribute as a String type (you can customize the type)
# self.class.attribute attr_name.to_sym, :string
# end
-2
View File
@@ -1,2 +0,0 @@
module ArticlesHelper
end
+2
View File
@@ -0,0 +1,2 @@
module BrokersHelper
end
+2
View File
@@ -0,0 +1,2 @@
module CarriersHelper
end
-2
View File
@@ -1,2 +0,0 @@
module CommentsHelper
end
-2
View File
@@ -1,2 +0,0 @@
module IdCardEmployersHelper
end
+2
View File
@@ -0,0 +1,2 @@
module ProviderGroupsHelper
end
+2
View File
@@ -0,0 +1,2 @@
module ProvidersHelper
end
-2
View File
@@ -1,2 +0,0 @@
module WelcomeHelper
end
+11 -4
View File
@@ -2,8 +2,15 @@
import "@hotwired/turbo-rails" import "@hotwired/turbo-rails"
import "trix" import "trix"
import "@rails/actiontext" import "@rails/actiontext"
import { Application } from "@hotwired/stimulus" // import { Application } from "@hotwired/stimulus"
import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading" // import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading"
import "controllers"
// import { createIcons, icons } from "lucide-static";
// document.addEventListener("turbo:load", () => {
// createIcons({ icons });
// });
// const application = Application.start()
// eagerLoadControllersFrom("controllers", application)
const application = Application.start()
eagerLoadControllersFrom("controllers", application)
@@ -4,19 +4,23 @@ export default class extends Controller {
static values = { static values = {
formColor: { type: Array, default: [] } // Declares 'items' as an Array value 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.preventDefault()
event.stopPropagation() 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) // this.containerTarget.insertAdjacentHTML("beforeend", content)
} }
remove(event) { removeExemption(event) {
event.preventDefault(); event.preventDefault();
const wrapper = event.target.closest(".network-item"); const wrapper = event.target.closest(".network-item");
if (wrapper.dataset.newRecord === "true") { if (wrapper.dataset.newRecord === "true") {
@@ -30,22 +34,19 @@ export default class extends Controller {
} }
} }
#updateTemplateNetwork() { #newExemption() {
const nextIndex = this.networkLogoTargets.length const nextIndex = this.exceptionTargets.length
const num_of_colors = this.formColorValue.length const num_of_colors = this.formColorValue.length
let colorIndex = 0 let colorIndex = 0
let newSecondaryColor = "copper"
if (nextIndex != 0) { if (nextIndex != 0) {
colorIndex = nextIndex % num_of_colors colorIndex = nextIndex % num_of_colors
if (nextIndex % 2 == 1) {
newSecondaryColor = "bronze"
}
} }
const newColor = this.formColorValue[colorIndex] const newColor = this.formColorValue[colorIndex]
return this.templateTarget.innerHTML
return this.exceptionTemplateTarget.innerHTML
.replace(/NEW_RECORD/g, nextIndex) .replace(/NEW_RECORD/g, nextIndex)
.replace(/NEXT_COLOR/g, newColor) .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() { #updateTemplatePlan() {
const nextIndex = this.planTargets.length const nextIndex = this.planTargets.length
console.log(nextIndex)
const num_of_colors = this.formColorValue.length const num_of_colors = this.formColorValue.length
let colorIndex = 0 let colorIndex = 0
let newSecondaryColor = "copper" let newSecondaryColor = "copper"
@@ -2,7 +2,7 @@ import { Controller } from "@hotwired/stimulus";
export default class extends Controller { export default class extends Controller {
static values = { url: String }; static values = { url: String };
static targets = ["benefit"]; static targets = ["benefit", "title"];
connect() { connect() {
} }
@@ -14,19 +14,23 @@ export default class extends Controller {
return; 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 response = await fetch(url);
const templateBenefitsData = await response.json(); const templatePlanData = await response.json();
this.#updateFields(templateBenefitsData) this.#updateFields(templatePlanData)
} }
clearFields() { clearFields() {
} }
async #updateFields(templateBenefitsData) { async #updateFields(templatePlanData) {
const titleElement = this.titleTarget
if (!titleElement.value) {
titleElement.value = templatePlanData.title.match(/^(.*\d)k(?=\d)/i)[0].replace(/(\d)/, ' $1')
}
const benefitTargetsList = this.benefitTargets const benefitTargetsList = this.benefitTargets
templateBenefitsData.forEach(function(bene) { templatePlanData.plan_benefits.forEach(function(bene) {
const targetElement = benefitTargetsList.find( const targetElement = benefitTargetsList.find(
(element) => element.dataset.sequence == bene.sequence (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,35 @@
// app/javascript/controllers/font_validator_controller.js
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static targets = ["textField", "hiddenField", "countDisplayField"]
connect() {
this.measure()
}
measure() {
const text = this.textFieldTarget.value
const pixelWidth = this.getTextWidth(text, "bold 6px sans-serif")
// Do something with the pixel width (e.g., store in a hidden field for Rails to read)
if (this.hasHiddenFieldTarget) {
this.hiddenFieldTarget.value = pixelWidth
this.countDisplayFieldTarget.textContent = `${pixelWidth}`
if (pixelWidth > 100) {
this.countDisplayFieldTarget.classList.add("text-brightlava")
} else {
this.countDisplayFieldTarget.classList.remove("text-brightlava")
}
}
}
// Canvas measurement trick
getTextWidth(text, font) {
const canvas = document.createElement("canvas")
const context = canvas.getContext("2d")
context.font = font
const metrics = context.measureText(text)
return Math.ceil(metrics.width)
}
}
@@ -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");
}
}
}
}
@@ -1,16 +0,0 @@
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}!`
}
}
+3 -6
View File
@@ -1,11 +1,8 @@
// Import and register all your controllers from the importmap under controllers/* // This file is auto-generated by ./bin/rails stimulus:manifest:update
// Run that command whenever you add a new controller or create them with
// ./bin/rails generate stimulus controllerName
import { application } from "controllers/application" import { application } from "controllers/application"
// Eager load all controllers defined in the import map under controllers/**/*_controller // Eager load all controllers defined in the import map under controllers/**/*_controller
import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading" import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading"
eagerLoadControllersFrom("controllers", application) eagerLoadControllersFrom("controllers", application)
// Lazy load controllers as they appear in the DOM (remember not to preload controllers in import map!)
// import { lazyLoadControllersFrom } from "@hotwired/stimulus-loading"
// lazyLoadControllersFrom("controllers", application)
@@ -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,107 @@
import { Controller } from "@hotwired/stimulus"; import { Controller } from "@hotwired/stimulus";
export default class extends Controller { export default class extends Controller {
static targets = ["preview", "previewContainer", "logoSelect", "logofield", "initialLogoFile"]; static values = {
logoType: String,
employerName: String,
employerId: Number
}
static targets = ["preview", "previewContainer", "logoSelect", "logoIdField", "logoNameField", "initialLogoFile"];
async connect() { async connect() {
console.log(this.logofieldTarget.value) console.log('in connect');
if (this.logofieldTarget.value.includes("Logo.")) { this.setPreviewImage()
const response = await fetch(`/card_logo_files/${this.logofieldTarget.value}/image`); // Fetch the binary data // 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 blob = await response.blob();
const objectUrl = URL.createObjectURL(blob); const objectUrl = URL.createObjectURL(blob);
this.previewTarget.src = objectUrl; this.previewTarget.src = objectUrl;
this.previewContainerTarget.classList.remove("hidden"); 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) { uploadLogo(event) {
console.log('in uploadLogo'); console.log('in uploadLogo');
event.preventDefault() event.preventDefault()
const file = event.target.files[0]; let logoFile = event.target.files[0];
if (!file) return; if (!logoFile) return;
const logoType = event.params.type const logoType = this.logoTypeValue
let newFileName = file.name let newFileName = logoFile.name
if (logoType == "network") { if (logoType == "network") {
console.log("n " + newFileName); console.log("n " + newFileName);
newFileName = this.determineNetworkFilename(file) newFileName = this.determineNetworkFilename(logoFile)
this.addOptionToSelect(newFileName)
} else if (logoType == "employer") { } else if (logoType == "employer") {
newFileName = this.determineEmployerFilename(file) newFileName = this.determineEmployerFilename(logoFile)
this.logofieldTarget.value = newFileName;
} }
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); })
.catch((error) => {
// this.uploadLogoToServer(file); // Handle any errors that occurred
console.error(error);
});
} }
previewFile(file) { previewFile(logoFile) {
console.log('in previewFile'); console.log('in previewFile');
const reader = new FileReader(); const reader = new FileReader();
reader.onload = (e) => { reader.onload = (e) => {
this.previewTarget.src = e.target.result; this.previewTarget.src = e.target.result;
this.previewContainerTarget.classList.remove("hidden"); this.previewContainerTarget.classList.remove("hidden");
}; };
reader.readAsDataURL(file); reader.readAsDataURL(logoFile);
} }
async uploadLogoToServer(file) { async uploadLogoToServer(logoFile) {
console.log('in uploadLogoToServer'); console.log('in uploadLogoToServer');
const employerId = this.employerIdValue
const formData = new FormData(); const formData = new FormData();
formData.append("card_logo_file[logo_file]", file); formData.append(`id_card_${this.logoTypeValue}_logo[logo_file]`, logoFile);
formData.append("card_logo_file[logo_type]", "employer"); if (employerId) {
formData.append(`id_card_${this.logoTypeValue}_logo[employer_id]`, employerId);
}
const csrfToken = document.querySelector("meta[name='csrf-token']").content; const csrfToken = document.querySelector("meta[name='csrf-token']").content;
try { try {
const response = await fetch("/card_logo_files/", { const response = await fetch(`/id_card/${this.logoTypeValue}_logos/`, {
method: "POST", method: "POST",
headers: { headers: {
"X-CSRF-Token": csrfToken "X-CSRF-Token": csrfToken
@@ -70,39 +111,41 @@ export default class extends Controller {
if (response.ok) { if (response.ok) {
console.log('Upload successful!') console.log('Upload successful!')
const data = await response.json();
return data;
} else { } else {
console.error("Failed to track event."); throw new Error(`HTTP error! status: ${response.status}`);
} }
} catch (error) { } catch (error) {
console.error("Network error:", error); console.error("Network error:", error);
throw new Error("Network error:", error);
} }
} }
addOptionToSelect(name) { addOptionToSelect(name, id) {
const blankOptionIndex = 0; 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) { if (this.logoIdFieldTarget.options.length > blankOptionIndex + 1) {
this.logoSelectTarget.insertBefore(newOption, this.logoSelectTarget.options[blankOptionIndex + 1]); this.logoIdFieldTarget.insertBefore(newOption, this.logoIdFieldTarget.options[blankOptionIndex + 1]);
} else { } else {
this.logoSelectTarget.appendChild(newOption); this.logoIdFieldTarget.appendChild(newOption);
} }
this.logoSelectTarget.value = name;
} }
determineNetworkFilename(file) { determineNetworkFilename(logoFile) {
const fileExtension = file.name.split('.').pop(); const fileExtension = logoFile.name.split('.').pop();
const primaryNetworkName = prompt("Enter the name for the primary network (Usually 'Cigna' or 'MedCost':"); 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(' ', ''); const logoFilename = this.titleizeText(primaryNetworkName).concat(this.titleizeText(secondaryNetworkName)).concat("Logo.").concat(fileExtension).replaceAll(' ', '');
return logoFilename return logoFilename
} }
determineEmployerFilename(file) { determineEmployerFilename(logoFile) {
const fileExtension = file.name.split('.').pop(); const fileExtension = logoFile.name.split('.').pop();
const employerName = prompt("Enter the name for the new Employer (minus any 'The's, 'LLC', or 'Health Plan'):"); const employerName = this.employerNameValue
const logoFilename = this.titleizeText(employerName).concat("Logo.").concat(fileExtension).replaceAll(' ', ''); const logoFilename = this.titleizeText(employerName).concat("Logo.").concat(fileExtension).replaceAll(' ', '');
return logoFilename 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 = 9
this.providerSectionFieldTarget.value = 5
} else if (pnValue == "MedCost") {
this.networkLogoFieldTarget.value = 7
this.providerSectionFieldTarget.value = 4
} else {
this.networkLogoFieldTarget.value = ""
this.providerSectionFieldTarget.value = ""
}
const event = new Event('change', { bubbles: true });
this.networkLogoFieldTarget.dispatchEvent(event);
}
}
+116
View File
@@ -0,0 +1,116 @@
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
member_attributes.merge!({dental_coverage: member.coverage_class.upcase})
if member.dental_plan_key && member.id_card_plan_id.blank?
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
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
+150
View File
@@ -0,0 +1,150 @@
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.build_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.assign_attributes(employer_update_attrs)
if !employer.save && full_sync
employer.save(validate: false)
end
if !employer.initialized && [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 || id_card_setup.print_name.blank?
setup_update_attrs.merge!({
print_name: determine_card_print_name(pb_company_plan.company_pb_entity_key, pl_plan_key)
})
end
if id_card_setup.pl_plan_key.blank? && employer.pl_plan_key.present?
setup_update_attrs.merge!({
pl_plan_key: employer.pl_plan_key
})
end
id_card_setup.assign_attributes(setup_update_attrs)
if !id_card_setup.save && full_sync
id_card_setup.save(validate: false)
end
# 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
+109
View File
@@ -0,0 +1,109 @@
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], 3.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"
').select('
"GEN_LookupTables".*, "PBProductParticipation"."InEffect" AS EffDate
').where('
"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
).order('EffDate DESC').first.short_desc
member.coverage_class = coverage_class
else
member.coverage_class = "NONE"
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
member.save!
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
-16
View File
@@ -1,16 +0,0 @@
class AlternateNetworkLogo < ApplicationRecord
belongs_to :employer
# before_save :process_network_logo
def process_network_logo
if self.network_logo.present? && !self.network_logo.is_a?(String)
self.employer_setup_process.card_logo_files.new(
filename: self.network_logo.filename,
logo_type: 'network',
image: self.network_logo.data,
pl_plan_key: self.employer_setup_process.pl_plan_key || ""
)
end
end
end
+1 -1
View File
@@ -3,5 +3,5 @@
class ApplicationRecord < ActiveRecord::Base class ApplicationRecord < ActiveRecord::Base
primary_abstract_class primary_abstract_class
establish_connection :baclight establish_connection :primary
end end
+5
View File
@@ -0,0 +1,5 @@
class BatchProcess < ApplicationRecord
end
-21
View File
@@ -1,21 +0,0 @@
module BrittonWeb
class Employers < BrittonWebRecord
# self.table_name = 'employers'
alias_attribute :id, :id
alias_attribute :name, :name
alias_attribute :pl_plan_key, :pl_plan_key
alias_attribute :plan_id, :plan_id
alias_attribute :dental_plan, :dental_plan
alias_attribute :single_card_template, :single_card_template
alias_attribute :multiple_card_template, :multiple_card_template
alias_attribute :logo, :logo
alias_attribute :active, :active
alias_attribute :broker_id, :broker_id
alias_attribute :created_at, :created_at
alias_attribute :updated_at, :updated_at
end
end
-17
View File
@@ -1,17 +0,0 @@
module BrittonWeb
class NetworkLogos < BrittonWebRecord
self.table_name = 'network_logos'
alias_attribute :id, :id
alias_attribute :net_logo, :net_logo
alias_attribute :exception_type, :exception_type
alias_attribute :exception_value, :exception_value
alias_attribute :default, :default
alias_attribute :employer_id, :employer_id
alias_attribute :created_at, :created_at
alias_attribute :updated_at, :updated_at
end
end
+4
View File
@@ -0,0 +1,4 @@
class Broker < ApplicationRecord
belongs_to :carrier
has_many :employers
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
+3
View File
@@ -0,0 +1,3 @@
class Carrier < ApplicationRecord
has_many :brokers
end
+103
View File
@@ -0,0 +1,103 @@
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, -> {
left_outer_joins(:id_card_setup)
.where(initialized: false)
.or(
where(id_card_setup: {initialized: false})
).distinct
}
scope :missing_keychain_initialization, -> {
uninitialized.automation_ready
}
scope :uninitialized_id_card_setup, -> {
left_outer_joins(:id_card_setup)
.where(id_card_setup: {initialized: false})
}
scope :missing_plans, -> {
left_outer_joins(:plans)
.where(id_card_plans: { pb_product_key: [nil, ""] })
.distinct
}
scope :has_plans, -> {
left_outer_joins(:plans)
.where("id_card_plans.pb_product_key IS NOT NULL AND id_card_plans.pb_product_key != ''")
.distinct
}
scope :missing_members, -> {
left_outer_joins(:members)
.where(members: { id: nil })
.distinct
}
scope :has_members, -> {
left_outer_joins(:members)
.where.not(members: { id: nil })
.distinct
}
scope :missing_plans_initialization, -> {
initialized.uninitialized_id_card_setup.missing_plans
}
scope :missing_members_initialization, -> {
initialized.uninitialized_id_card_setup.has_plans.missing_members
}
scope :ready_for_id_card_activation, -> {
initialized.uninitialized_id_card_setup.has_members
}
scope :with_active_id_card_setup, -> {
active.left_outer_joins(:id_card_setup)
.where(id_card_setup: {active: true})
}
scope :deactivated, -> {
inactive.initialized
}
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
+7
View File
@@ -0,0 +1,7 @@
module MemberAutomation
extend ActiveSupport::Concern
def sync_with_vhcs
AutomationService::MemberUpdate.new(self.employer.pl_plan_key, self.pb_entity_key).call
end
end
+55 -84
View File
@@ -1,105 +1,77 @@
class Employer < ApplicationRecord class Employer < ApplicationRecord
has_many :members include EmployerAutomation
has_many :plans, dependent: :destroy belongs_to :broker, optional: true
accepts_nested_attributes_for :plans, allow_destroy: true, reject_if: :all_blank 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
has_many :print_data, class_name: 'IdCard::PrintData', dependent: :destroy
has_many :alternate_network_logos, dependent: :destroy validates :name, :slug, :effective_date, presence: true
accepts_nested_attributes_for :alternate_network_logos, allow_destroy: true, reject_if: :all_blank validates :group_number, :pl_plan_key, :company_pb_entity_key, :plan_id, presence: true, if: -> { initialized }
has_many :employer_card_logos, dependent: :destroy validates :name, :slug, :group_number, :pl_plan_key, :company_pb_entity_key, :plan_id, uniqueness: true, allow_blank: true
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
scope :active, -> { where(active: true) } scope :active, -> { where(active: true) }
scope :inactive, -> { where(active: false) } scope :inactive, -> { where(active: false) }
before_validation :create_slug, if: :will_save_change_to_name?
before_validation :active_initialized_check, if: :will_save_change_to_active?
# before_save :process_employer_logo def create_slug
# before_save :process_employer_logo, if: :employer_logo_filename_changed? self.slug = Employer.employer_trim_name(name).parameterize
before_save :create_slug, if: :new_record? end
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 active_initialized_check
if active
self.initialized = true
end
if active == false
id_card_setup&.update(active: false)
end end
end end
def create_slug def id_card_enabled?
self.slug = employer_trim_name(self.name).parameterize 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 employer_member_keys_by_plan(pb_product_key)
{
pl_plan_key: self.pl_plan_key,
member_keys: self.plans.find_by(pb_product_key: pb_product_key).members.pluck(:pb_entity_key)
}
end end
def name_to_logo_filename(extension) 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 end
def employer_trim_name(name) def self.employer_trim_name(employer_name)
regex_source = Regexp.union(["health", "plan", "the", "inc", "llc"]).source # 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") 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 end
def self.permitted_params(params) def self.permitted_params(params)
params.require(:employer).permit( params.require(:employer).permit(
:name, :name,
:slug,
:group_number, :group_number,
:pl_plan_key, :pl_plan_key,
:effective_date, :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
]
) )
end end
@@ -111,24 +83,23 @@ class Employer < ApplicationRecord
medical_number: self.group_number, medical_number: self.group_number,
dental_number: '', dental_number: '',
plan_key: self.pl_plan_key, 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 rx_info = self.id_card_setup.rx_section
fairos_info = Vhcs::HlrxCrosRef.where(pl_plan_key: 52).first
Vhcs::HlrxCrosRef.create!( Vhcs::HlrxCrosRef.create!(
group_no: self.group_number, group_no: self.group_number,
rx_group_id: self.group_number, rx_group_id: self.group_number,
help_desk: fairos_info.help_desk, help_desk: rx_info.help_desk,
customer_service: fairos_info.customer_service, customer_service: rx_info.customer_service,
web_url: fairos_info.web_url, web_url: rx_info.web_url,
pl_plan_key: self.pl_plan_key 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| plan.plan_benefits.each do |bene|
Vhcs::HlEgglestonCardBenefit.create!( Vhcs::HlEgglestonCardBenefit.create!(
plan_id: plan.plan_id, plan_id: plan.pb_product_key,
benefit_desc: bene.benefit_desc, benefit_desc: bene.benefit_desc,
benefit: bene.benefit, benefit: bene.benefit,
sequence: bene.sequence, sequence: bene.sequence,
-5
View File
@@ -1,5 +0,0 @@
class EmployerCardLogo < ApplicationRecord
belongs_to :employer
belongs_to :card_logo_file
end
-106
View File
@@ -1,106 +0,0 @@
class EmployerSetupProcess < ApplicationRecord
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 :card_logo_files
# before_save :process_employer_logo
before_save :create_slug, if: :new_record?
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
end
def create_slug
self.slug = employer_trimmed_name.parameterize
end
def employer_name_to_logo_filename(extension)
self.employer_trimmed_name.titleize.gsub(/\s+/, '').concat('Logo').concat(extension.downcase)
end
def employer_trimmed_name
regex_source = Regexp.union(["health", "plan", "the", "inc", "llc"]).source
case_insensitive_regex = Regexp.new(regex_source, "i")
self.employer_name.gsub(case_insensitive_regex, "").squish
end
def self.permitted_params(params)
params.require(:employer_setup_process).permit(
:employer_name,
:group_number,
:pl_plan_key,
:effective_date,
:employer_logo,
:network_provider,
plans_attributes: [
:id,
:title,
:plan_id,
:_destroy,
plan_benefits_attributes: [
:id,
:benefit_desc,
:benefit,
:sequence,
:_destroy,
]
],
alternate_network_logos_attributes: [
:id,
:network_logo,
:exception_type,
:exception_value,
:_destroy
]
)
end
def save_to_prod
VhcsRecord.transaction do
Vhcs::HlPlanCode.create!(
group_number: self.group_number,
medical_number: self.group_number,
dental_number: '',
plan_key: self.pl_plan_key,
effect_date: self.effective_date
)
# Replace fairos_info with template like for benefits
fairos_info = Vhcs::HlrxCrosRef.where(pl_plan_key: 52).first
Vhcs::HlrxCrosRef.cdarreate!(
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,
pl_plan_key: self.pl_plan_key
)
self.plans.each_with_index do |plan, i|
plan.plan_benefits.each do |bene|
Vhcs::HlEgglestonCardBenefit.create!(
plan_id: plan.plan_id,
benefit_desc: bene.benefit_desc,
benefit: bene.benefit,
sequence: bene.sequence,
plan_key: self.pl_plan_key
)
end
end
end
end
end
+14
View File
@@ -0,0 +1,14 @@
module HebWeb
class BrokerXRef < HebWebRecord
self.table_name = 'BrokerXRef'
alias_attribute :id, :Id
alias_attribute :pl_plan_key, :PLPlanKey
alias_attribute :pb_entity_key, :PBEntityKey
alias_attribute :plan_name, :PlanName
alias_attribute :employer_pl_plan_key, :EmployerPLPlanKey
end
end
+4
View File
@@ -0,0 +1,4 @@
class HebWebRecord < ActiveRecord::Base
self.abstract_class = true
connects_to database: { writing: :heb_web, reading: :heb_web }
end
+5
View File
@@ -0,0 +1,5 @@
module IdCard
def self.table_name_prefix
"id_card_"
end
end
+33
View File
@@ -0,0 +1,33 @@
module IdCard
class EmployerLogo < ApplicationRecord
belongs_to :setup, optional: true
validates :filename, :image_data, :content_type, :aspect_ratio, presence: true
validates :filename, uniqueness: true
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
end
end
+53
View File
@@ -0,0 +1,53 @@
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
validates :exception_type, :exception_values, presence: true
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,45 @@
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
validates :field_name, presence: true
validates :field_name, uniqueness: { scope: :field_exception_id }
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
+46
View File
@@ -0,0 +1,46 @@
module IdCard
class NetworkLogo < ApplicationRecord
validates :filename, :image_data, :content_type, :aspect_ratio, presence: true
validates :filename, uniqueness: true
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
end
end
+87
View File
@@ -0,0 +1,87 @@
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
has_many :members, class_name: 'Member', foreign_key: :id_card_plan_id
validates :title, presence: true
validates :pb_product_key, :pl_plan_key, presence: true, if: -> { setup&.active }
validates :pb_product_key, uniqueness: true, allow_nil: true
validate :validate_plan_benefits_count, unless: -> { template }
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 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 validate_plan_benefits_count
plan_benefits_size = plan_benefits.size
template_benefits_size = case setup&.card_template
when "TandemlocIDCard"
TANDEMLOC_BENEFIT_FIELDS.size
when "SmartIDCard"
SMART_BENEFIT_FIELDS.size
else
FARIOS_BENEFIT_FIELDS.size
end
unless plan_benefits_size == template_benefits_size
errors.add(:base, "Plan Benefits size (#{plan_benefits_size}) does not match ID Card Template (#{template_benefits_size})")
end
end
end
end
+8
View File
@@ -0,0 +1,8 @@
module IdCard
class PlanBenefit < ApplicationRecord
belongs_to :plan
validates :benefit_desc, :sequence, presence: true
validates :benefit, presence: true, unless: :new_record?
end
end
+26
View File
@@ -0,0 +1,26 @@
module IdCard
class PrintData < ApplicationRecord
belongs_to :employer, class_name: 'Employer'
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
private
def has_jasper_sorting_fields
missing_sample_card_fields = sample_plan_title.blank?
missing_member_card_fields = employer_name.blank? || full_name_last_name_first.blank?
if missing_sample_card_fields || missing_member_card_fields
errors.add(:base, "Required field for Jasper Server is missing")
end
end
def assign_blank_strings_to_unassigned_params
STRING_ATTRIBUTES.each do |attr|
self[attr] = "" if self[attr].blank?
end
end
end
end
+45
View File
@@ -0,0 +1,45 @@
module IdCard
class ProviderSection < ApplicationRecord
scope :defaults, -> { where(default: true) }
def self.permitted_params(params)
params.require(:id_card_setup).require(:provider_section).permit(
:title,
: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
def display_title
if self.default
"Default #{self.title}"
else
self.title
end
end
end
end
+5
View File
@@ -0,0 +1,5 @@
module IdCard
class RxSection < ApplicationRecord
end
end
+120
View File
@@ -0,0 +1,120 @@
module IdCard
class Setup < ApplicationRecord
belongs_to :employer, class_name: 'Employer'
belongs_to :network_logo, optional: true
belongs_to :provider_section, optional: true
belongs_to :rx_section, optional: true
has_one :employer_logo, dependent: :destroy
has_many :plans, dependent: :destroy
has_many :field_exceptions, dependent: :destroy
validates :print_name, :network_provider, :card_template, :employer_logo, :network_logo_id,
:provider_section_id, :rx_section_id, presence: true, unless: :new_record?
validates :pl_plan_key, :rx_group_number, presence: true, if: -> { initialized }
validate :validate_print_name_fits_on_card
attr_accessor :print_name_pixel_width
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-vivid', 'cobalt-vivid', 'bluemana']
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 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?
field_exceptions.present?
end
def sample_card_print_ready?
print_name.present? &&
card_template.present? &&
employer_logo.present? &&
network_logo_id.present? &&
provider_section_id.present? &&
rx_section_id.present? &&
plans.present?
end
def member_cards_print_ready?
sample_card_print_ready? &&
plans.present? &&
plans.all? { |plan| plan.pb_product_key.present? } &&
employer.members.present?
end
def activation_ready?
member_cards_print_ready? && !active
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)
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,
:print_name_pixel_width,
:network_provider,
:card_template,
:rx_group_number,
:network_logo_id,
:rx_section_id,
:provider_section_id
)
end
private
def validate_print_name_fits_on_card
if print_name_pixel_width.to_i > 100
errors.add(:print_name, "Too Long For Card")
end
end
end
end
-3
View File
@@ -1,3 +0,0 @@
class IdCardBenefit < ApplicationRecord
belongs_to :id_card_benefits_template
end
-5
View File
@@ -1,5 +0,0 @@
class IdCardBenefitsTemplate < ApplicationRecord
has_many :id_card_benefits, dependent: :destroy
end
+30 -1
View File
@@ -1,6 +1,35 @@
class Member < ApplicationRecord class Member < ApplicationRecord
belongs_to :plan include MemberAutomation
belongs_to :id_card_plan, class_name: 'IdCard::Plan', optional: true
belongs_to :employer belongs_to :employer
serialize :dependents, coder: JSON
validates :pb_entity_key, presence: true
validates :name, :family_id, :mb_member_key, :pl_plan_key,
:id_card_display_name, presence: true, unless: :new_record?
validates :division, presence: true, if: -> { employer.id_card_setup.has_divisions }
# validates :coverage_class, :dental_plan_key, presence: true, if: -> { employer.id_card_setup.has_dental }
validates :mb_member_key, :pb_entity_key, uniqueness: true
validates :name, uniqueness: { scope: :employer_id }
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 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
+2
View File
@@ -0,0 +1,2 @@
class Provider < ApplicationRecord
end

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