diff --git a/Gemfile b/Gemfile index b5ab2c1..fa5d223 100644 --- a/Gemfile +++ b/Gemfile @@ -3,7 +3,7 @@ source "https://rubygems.org" git_source(:github) { |repo| "https://github.com/#{repo}.git" } -ruby "3.3.9" +ruby "3.4.8" # Bundle edge Rails instead: # gem "rails", github: "rails/rails", branch: "7-2-stable" @@ -87,4 +87,5 @@ gem 'rubyzip' gem 'httparty' gem 'combine_pdf' gem 'rails_icons' -gem 'fastimage' \ No newline at end of file +gem 'fastimage' +gem 'rubyzip', require: 'zip' \ No newline at end of file diff --git a/Gemfile.lock b/Gemfile.lock index 2e188b3..bd1fa19 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -434,7 +434,7 @@ DEPENDENCIES web-console RUBY VERSION - ruby 3.3.9p170 + ruby 3.4.8p72 BUNDLED WITH 2.5.22 diff --git a/app/controllers/employers_controller.rb b/app/controllers/employers_controller.rb index 901b215..4a67fae 100644 --- a/app/controllers/employers_controller.rb +++ b/app/controllers/employers_controller.rb @@ -11,7 +11,7 @@ class EmployersController < ApplicationController @employer = Employer.new @employer.build_plan_with_default_benefits @plan_templates = IdCardBenefitsTemplate.where.not(title: "BLANK") - render :new + render :new_new end def import @@ -23,7 +23,7 @@ class EmployersController < ApplicationController @employer = Employer.new @employer.build_plan_with_default_benefits end - render :new + render :new_new end def create @@ -37,7 +37,7 @@ class EmployersController < ApplicationController redirect_to employer_path(@employer.slug), notice: 'Employer Saved' else @plan_templates = IdCardBenefitsTemplate.where.not(title: "BLANK") - render :new + render :new_new end end diff --git a/app/controllers/sample_id_cards_controller.rb b/app/controllers/sample_id_cards_controller.rb index 4a08a7d..caa8911 100644 --- a/app/controllers/sample_id_cards_controller.rb +++ b/app/controllers/sample_id_cards_controller.rb @@ -14,7 +14,7 @@ class SampleIdCardsController < ApplicationController def generate_print @employer = Employer.find_by(slug: params[:employer_slug]) - sample_cards_pdf = EmployerCardsGenerator.new(@employer).call + sample_cards_pdf = EmployerCardsGenerator.new(@employer, "PrintCard").call send_data sample_cards_pdf.to_pdf, filename: "#{@employer.name.parameterize(separator: "_")}_print_cards_#{Date.today}.pdf", @@ -22,4 +22,27 @@ class SampleIdCardsController < ApplicationController disposition: 'attachment' end + + def generate_mobile_display + @employer = Employer.find_by(slug: params[:employer_slug]) + sample_cards_pdf = EmployerCardsGenerator.new(@employer, "MobileDisplayCard").call + + send_data sample_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]) + sample_cards_pdf = EmployerCardsGenerator.new(@employer, "FullPageCard").call + + sample_cards_pdf.rewind + send_data sample_cards_pdf.sysread, + filename: "#{@employer.name.parameterize(separator: "_")}_full_page_cards_#{Date.today}.zip", + type: 'application/zip', + disposition: 'attachment' + + end end \ No newline at end of file diff --git a/app/form_builders/tailwind_form_builder.rb b/app/form_builders/tailwind_form_builder.rb index d678454..3b037e9 100644 --- a/app/form_builders/tailwind_form_builder.rb +++ b/app/form_builders/tailwind_form_builder.rb @@ -70,7 +70,7 @@ class TailwindFormBuilder < ActionView::Helpers::FormBuilder text, label_opts = if label_options.present? [label_options[:text], label_options.except(:text)] else - [nil, {}] + [object_method.to_s.titleize, {}] end label_classes = label_opts[:class] || "block text-platinum font-bold md:text-right mb-1 md:mb-0 pr-4" diff --git a/app/javascript/controllers/add_alt_network_logo_controller.js b/app/javascript/controllers/add_exception_controller.js similarity index 66% rename from app/javascript/controllers/add_alt_network_logo_controller.js rename to app/javascript/controllers/add_exception_controller.js index 6edf386..bd235f1 100644 --- a/app/javascript/controllers/add_alt_network_logo_controller.js +++ b/app/javascript/controllers/add_exception_controller.js @@ -4,19 +4,23 @@ export default class extends Controller { static values = { formColor: { type: Array, default: [] } // Declares 'items' as an Array value } - static targets = ["template", "container", "networkLogo", "button"] + static targets = ["exceptionTemplate", "exceptionContainer", "exception", "exceptionButton"] - add(event) { + connect(){ + console.log(this.formColorValue) + } + + addExemption(event) { event.preventDefault() event.stopPropagation() - const content = this.#updateTemplateNetwork() + const content = this.#newExemption() - this.buttonTarget.insertAdjacentHTML('beforebegin', content); + this.exceptionButtonTarget.insertAdjacentHTML('beforebegin', content); // this.containerTarget.insertAdjacentHTML("beforeend", content) } - remove(event) { + removeExemption(event) { event.preventDefault(); const wrapper = event.target.closest(".network-item"); if (wrapper.dataset.newRecord === "true") { @@ -30,22 +34,19 @@ export default class extends Controller { } } - #updateTemplateNetwork() { - const nextIndex = this.networkLogoTargets.length + #newExemption() { + const nextIndex = this.exceptionTargets.length const num_of_colors = this.formColorValue.length let colorIndex = 0 - let newSecondaryColor = "copper" if (nextIndex != 0) { colorIndex = nextIndex % num_of_colors - if (nextIndex % 2 == 1) { - newSecondaryColor = "bronze" - } } const newColor = this.formColorValue[colorIndex] - return this.templateTarget.innerHTML + + return this.exceptionTemplateTarget.innerHTML .replace(/NEW_RECORD/g, nextIndex) .replace(/NEXT_COLOR/g, newColor) - .replace(/NEXT_SECONDARY_COLOR/g, newSecondaryColor) } + } diff --git a/app/javascript/controllers/add_exception_item_controller.js b/app/javascript/controllers/add_exception_item_controller.js new file mode 100644 index 0000000..5d1e090 --- /dev/null +++ b/app/javascript/controllers/add_exception_item_controller.js @@ -0,0 +1,51 @@ +import { Controller } from "@hotwired/stimulus" + +export default class extends Controller { + static targets = ["exceptionItemTemplate", "exceptionItemContainer", "exceptionItem", "exceptionItemButton"] + + connect() { + 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 + 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) + + + } +} diff --git a/app/javascript/controllers/general_form_controller.js b/app/javascript/controllers/general_form_controller.js new file mode 100644 index 0000000..ac5b3af --- /dev/null +++ b/app/javascript/controllers/general_form_controller.js @@ -0,0 +1,43 @@ +import { Controller } from "@hotwired/stimulus" + +export default class extends Controller { + static targets = ["dependentField"] + + connect() { + } + + 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"); + } + } + } +} \ No newline at end of file diff --git a/app/javascript/controllers/logo_upload_controller.js b/app/javascript/controllers/logo_upload_controller.js index 62d07f3..ce0bd5a 100644 --- a/app/javascript/controllers/logo_upload_controller.js +++ b/app/javascript/controllers/logo_upload_controller.js @@ -4,6 +4,7 @@ export default class extends Controller { static targets = ["preview", "previewContainer", "logoSelect", "logofield", "initialLogoFile"]; async connect() { + console.log('in connect'); console.log(this.logofieldTarget.value) if (this.logofieldTarget.value.includes("Logo.")) { const response = await fetch(`/card_logo_files/${this.logofieldTarget.value}/image`); // Fetch the binary data @@ -82,13 +83,13 @@ export default class extends Controller { const blankOptionIndex = 0; const newOption = new Option(name, name, true, true) - if (this.logoSelectTarget.options.length > blankOptionIndex + 1) { - this.logoSelectTarget.insertBefore(newOption, this.logoSelectTarget.options[blankOptionIndex + 1]); + if (this.logofieldTarget.options.length > blankOptionIndex + 1) { + this.logofieldTarget.insertBefore(newOption, this.logofieldTarget.options[blankOptionIndex + 1]); } else { - this.logoSelectTarget.appendChild(newOption); + this.logofieldTarget.appendChild(newOption); } - this.logoSelectTarget.value = name; + this.logofieldTarget.value = name; } determineNetworkFilename(file) { diff --git a/app/models/card_exception.rb b/app/models/card_exception.rb new file mode 100644 index 0000000..fd3bc76 --- /dev/null +++ b/app/models/card_exception.rb @@ -0,0 +1,10 @@ +class CardException < ApplicationRecord + belongs_to :employer + has_many :card_exception_items + accepts_nested_attributes_for :card_exception_items, allow_destroy: true, reject_if: :all_blank + + VALID_TYPES = ['zipcode', 'state', 'family_id'] + + validates :type, inclusion: { in: VALID_TYPES, + message: "%{value} is not a valid exception type" } +end diff --git a/app/models/card_exception_item.rb b/app/models/card_exception_item.rb new file mode 100644 index 0000000..273187e --- /dev/null +++ b/app/models/card_exception_item.rb @@ -0,0 +1,25 @@ +class CardExceptionItem < ApplicationRecord + belongs_to :card_exception + belongs_to :card_logo_file, optional: true + belongs_to :card_provider, optional: true + + validate :only_one_exception_field_present + + FIELDS_TO_VALIDATE = [:field_value, :card_logo_file_id, :card_provider_id].freeze + + VALID_FIELD_NAMES = ['network_logo', 'provider_section', 'effective_date'] + + validates :field_name, inclusion: { in: VALID_FIELD_NAMES, + message: "%{value} is not a valid Id Card Field Name" } + + + 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 diff --git a/app/models/card_logo_file.rb b/app/models/card_logo_file.rb index 0f09caf..9c0d5fe 100644 --- a/app/models/card_logo_file.rb +++ b/app/models/card_logo_file.rb @@ -1,4 +1,14 @@ class CardLogoFile < ApplicationRecord has_many :employer_card_logos, dependent: :destroy has_many :employers, through: :employer_card_logos + + before_save :round_aspect_ratio + + private + + def round_aspect_ratio + if self.aspect_ratio.present? + self.aspect_ratio = self.aspect_ratio.round(2) + end + end end diff --git a/app/models/employer.rb b/app/models/employer.rb index 20a94e9..602d7bd 100644 --- a/app/models/employer.rb +++ b/app/models/employer.rb @@ -22,6 +22,9 @@ class Employer < ApplicationRecord belongs_to :card_provider, optional: true belongs_to :card_rx, optional: true + has_many :card_exceptions, dependent: :destroy + accepts_nested_attributes_for :card_exceptions, allow_destroy: true, reject_if: :all_blank + scope :active, -> { where(active: true) } scope :inactive, -> { where(active: false) } @@ -128,7 +131,7 @@ class Employer < ApplicationRecord self.plans.each_with_index do |plan, i| plan.plan_benefits.each do |bene| Vhcs::HlEgglestonCardBenefit.create!( - plan_id: plan.plan_id, + plan_id: plan.pb_product_key, benefit_desc: bene.benefit_desc, benefit: bene.benefit, sequence: bene.sequence, diff --git a/app/models/vhcs/hl_egg_id_card_dependent.rb b/app/models/vhcs/hl_egg_id_card_dependent.rb index 3bc0ffb..1d147f4 100644 --- a/app/models/vhcs/hl_egg_id_card_dependent.rb +++ b/app/models/vhcs/hl_egg_id_card_dependent.rb @@ -1,5 +1,5 @@ module Vhcs - class HLEggIdCardDependent < VhcsRecord + class HlEggIdCardDependent < VhcsRecord self.table_name = 'HLEggIdCardDependent' diff --git a/app/models/vhcs/hlid_card_egg_data.rb b/app/models/vhcs/hlid_card_egg_data.rb new file mode 100644 index 0000000..b9a2cff --- /dev/null +++ b/app/models/vhcs/hlid_card_egg_data.rb @@ -0,0 +1,219 @@ +module Vhcs + class HlidCardEggData < VhcsRecord + + self.table_name = 'HLIDCardEggData' + + alias_attribute :id, :ID + alias_attribute :facility, :Facility + alias_attribute :division, :Division + alias_attribute :full_name, :FullName + alias_attribute :ssn, :SSN + alias_attribute :medical_coverage, :MedicalCoverage + alias_attribute :medical_eff_date, :MedicalEffDate + alias_attribute :medical_group_num, :MedicalGroupNum + alias_attribute :dental_coverage, :DentalCoverage + alias_attribute :dental_eff_date, :DentalEffDate + alias_attribute :dental_group_num, :DentalGroupNum + alias_attribute :card_type, :CardType + alias_attribute :provider_code, :ProviderCode + alias_attribute :provider_line_1, :ProviderLine1 + alias_attribute :provider_line_2, :ProviderLine2 + alias_attribute :provider_line_3, :ProviderLine3 + alias_attribute :provider_line_4, :ProviderLine4 + alias_attribute :provider_line_5, :ProviderLine5 + alias_attribute :provider_line_6, :ProviderLine6 + alias_attribute :provider_line_7, :ProviderLine7 + alias_attribute :provider_line_8, :ProviderLine8 + alias_attribute :provider_line_9, :ProviderLine9 + alias_attribute :provider_line_1_0, :ProviderLine10 + alias_attribute :provider_line_1_1, :ProviderLine11 + alias_attribute :mail_to, :MailTo + alias_attribute :mail_to_2, :MailTo2 + alias_attribute :claim_to_1, :ClaimTo1 + alias_attribute :claim_to_2, :ClaimTo2 + alias_attribute :claim_to_3, :ClaimTo3 + alias_attribute :claim_to_4, :ClaimTo4 + alias_attribute :claim_to_5, :ClaimTo5 + alias_attribute :claim_to_6, :ClaimTo6 + alias_attribute :claim_to_7, :ClaimTo7 + alias_attribute :claim_to_8, :ClaimTo8 + alias_attribute :claim_to_9, :ClaimTo9 + alias_attribute :claim_to_1_0, :ClaimTo10 + alias_attribute :claim_to_1_1, :ClaimTo11 + alias_attribute :contact_line_1, :ContactLine1 + alias_attribute :contact_line_2, :ContactLine2 + alias_attribute :contact_line_3, :ContactLine3 + alias_attribute :group_number, :GroupNumber + alias_attribute :family_id, :FamilyId + alias_attribute :group_no, :GroupNo + alias_attribute :rx_group_id, :RXGroupID + alias_attribute :help_desk, :HelpDesk + alias_attribute :customer_service, :CustomerService + alias_attribute :web_url, :WebUrl + alias_attribute :expr_1, :Expr1 + alias_attribute :line_3, :Line3 + alias_attribute :dependent_1, :Dependent1 + alias_attribute :dependent_2, :Dependent2 + alias_attribute :dependent_3, :Dependent3 + alias_attribute :dependent_4, :Dependent4 + alias_attribute :dependent_5, :Dependent5 + alias_attribute :dependent_6, :Dependent6 + alias_attribute :dependent_7, :Dependent7 + alias_attribute :dependent_8, :Dependent8 + alias_attribute :ben_desc_1, :BenDesc1 + alias_attribute :ben_1, :Ben1 + alias_attribute :ben_desc_2, :BenDesc2 + alias_attribute :ben_2, :Ben2 + alias_attribute :ben_desc_3, :BenDesc3 + alias_attribute :ben_3, :Ben3 + alias_attribute :ben_desc_4, :BenDesc4 + alias_attribute :ben_4, :Ben4 + alias_attribute :ben_desc_5, :BenDesc5 + alias_attribute :ben_5, :Ben5 + alias_attribute :ben_desc_6, :BenDesc6 + alias_attribute :ben_6, :Ben6 + alias_attribute :ben_desc_7, :BenDesc7 + alias_attribute :ben_7, :Ben7 + alias_attribute :ben_desc_8, :BenDesc8 + alias_attribute :ben_8, :Ben8 + alias_attribute :ben_desc_9, :BenDesc9 + alias_attribute :ben_9, :Ben9 + alias_attribute :ben_desc_1_0, :BenDesc10 + alias_attribute :ben_1_0, :Ben10 + alias_attribute :ben_desc_1_1, :BenDesc11 + alias_attribute :ben_1_1, :Ben11 + alias_attribute :ben_desc_1_2, :BenDesc12 + alias_attribute :ben_1_2, :Ben12 + alias_attribute :ben_desc_1_3, :BenDesc13 + alias_attribute :ben_1_3, :Ben13 + alias_attribute :ben_desc_1_4, :BenDesc14 + alias_attribute :ben_1_4, :Ben14 + alias_attribute :pl_plan_key, :PLPlanKey + alias_attribute :primary_mb_member_key, :PrimaryMBMemberKey + alias_attribute :ppo_lookup_1, :PPOLookup1 + alias_attribute :ppo_lookup_2, :PPOLookup2 + alias_attribute :precert_1, :Precert1 + alias_attribute :precert_2, :Precert2 + alias_attribute :precert_3, :Precert3 + alias_attribute :precert_4, :Precert4 + alias_attribute :precert_5, :Precert5 + alias_attribute :precert_6, :Precert6 + alias_attribute :misc_data, :MiscData + alias_attribute :ppo_data, :PPOData + alias_attribute :ppo_data_2, :PPOData2 + alias_attribute :ppo_data_3, :PPOData3 + alias_attribute :last_name, :LastName + alias_attribute :provider_line_1_2, :ProviderLine12 + alias_attribute :claim_to_1_2, :ClaimTo12 + + def attributes + rails_like = { + id: self.id, + facility: self.facility, + division: self.division, + full_name: self.full_name, + ssn: self.ssn, + medical_coverage: self.medical_coverage, + medical_eff_date: self.medical_eff_date, + medical_group_num: self.medical_group_num, + dental_coverage: self.dental_coverage, + dental_eff_date: self.dental_eff_date, + dental_group_num: self.dental_group_num, + card_type: self.card_type, + provider_code: self.provider_code, + provider_line_1: self.provider_line_1, + provider_line_2: self.provider_line_2, + provider_line_3: self.provider_line_3, + provider_line_4: self.provider_line_4, + provider_line_5: self.provider_line_5, + provider_line_6: self.provider_line_6, + provider_line_7: self.provider_line_7, + provider_line_8: self.provider_line_8, + provider_line_9: self.provider_line_9, + provider_line_1_0: self.provider_line_1_0, + provider_line_1_1: self.provider_line_1_1, + mail_to: self.mail_to, + mail_to_2: self.mail_to_2, + claim_to_1: self.claim_to_1, + claim_to_2: self.claim_to_2, + claim_to_3: self.claim_to_3, + claim_to_4: self.claim_to_4, + claim_to_5: self.claim_to_5, + claim_to_6: self.claim_to_6, + claim_to_7: self.claim_to_7, + claim_to_8: self.claim_to_8, + claim_to_9: self.claim_to_9, + claim_to_1_0: self.claim_to_1_0, + claim_to_1_1: self.claim_to_1_1, + contact_line_1: self.contact_line_1, + contact_line_2: self.contact_line_2, + contact_line_3: self.contact_line_3, + group_number: self.group_number, + family_id: self.family_id, + group_no: self.group_no, + rx_group_id: self.rx_group_id, + help_desk: self.help_desk, + customer_service: self.customer_service, + web_url: self.web_url, + expr_1: self.expr_1, + line_3: self.line_3, + dependent_1: self.dependent_1, + dependent_2: self.dependent_2, + dependent_3: self.dependent_3, + dependent_4: self.dependent_4, + dependent_5: self.dependent_5, + dependent_6: self.dependent_6, + dependent_7: self.dependent_7, + dependent_8: self.dependent_8, + ben_desc_1: self.ben_desc_1, + ben_1: self.ben_1, + ben_desc_2: self.ben_desc_2, + ben_2: self.ben_2, + ben_desc_3: self.ben_desc_3, + ben_3: self.ben_3, + ben_desc_4: self.ben_desc_4, + ben_4: self.ben_4, + ben_desc_5: self.ben_desc_5, + ben_5: self.ben_5, + ben_desc_6: self.ben_desc_6, + ben_6: self.ben_6, + ben_desc_7: self.ben_desc_7, + ben_7: self.ben_7, + ben_desc_8: self.ben_desc_8, + ben_8: self.ben_8, + ben_desc_9: self.ben_desc_9, + ben_9: self.ben_9, + ben_desc_1_0: self.ben_desc_1_0, + ben_1_0: self.ben_1_0, + ben_desc_1_1: self.ben_desc_1_1, + ben_1_1: self.ben_1_1, + ben_desc_1_2: self.ben_desc_1_2, + ben_1_2: self.ben_1_2, + ben_desc_1_3: self.ben_desc_1_3, + ben_1_3: self.ben_1_3, + ben_desc_1_4: self.ben_desc_1_4, + ben_1_4: self.ben_1_4, + pl_plan_key: self.pl_plan_key, + primary_mb_member_key: self.primary_mb_member_key, + ppo_lookup_1: self.ppo_lookup_1, + ppo_lookup_2: self.ppo_lookup_2, + precert_1: self.precert_1, + precert_2: self.precert_2, + precert_3: self.precert_3, + precert_4: self.precert_4, + precert_5: self.precert_5, + precert_6: self.precert_6, + misc_data: self.misc_data, + ppo_data: self.ppo_data, + ppo_data_2: self.ppo_data_2, + ppo_data_3: self.ppo_data_3, + last_name: self.last_name, + provider_line_1_2: self.provider_line_1_2, + claim_to_1_2: self.claim_to_1_2, + } + super.merge(rails_like) + end + + + end +end \ No newline at end of file diff --git a/app/models/vhcs/hlid_cards_egg.rb b/app/models/vhcs/hlid_cards_egg.rb index b96fdd2..1661c96 100644 --- a/app/models/vhcs/hlid_cards_egg.rb +++ b/app/models/vhcs/hlid_cards_egg.rb @@ -1,5 +1,5 @@ module Vhcs - class HLIDCardsEgg < VhcsRecord + class HlidCardsEgg < VhcsRecord self.table_name = 'HLIDCardsEgg' diff --git a/app/queries/call_stored_proc.rb b/app/queries/call_stored_proc.rb new file mode 100644 index 0000000..5a8bb49 --- /dev/null +++ b/app/queries/call_stored_proc.rb @@ -0,0 +1,14 @@ +class CallStoredProc + def initialize(procedure_name, args = {}) + @procedure_name = procedure_name + @args = args + end + + def call + params_sql = @args.map { |key, value| "@#{key} = :#{key}" }.join(', ') + sql_template = "EXEC #{@procedure_name} #{params_sql}" + sanitized_sql = VhcsRecord.send(:sanitize_sql_array, [sql_template, @args]) + + VhcsRecord.connection.exec_query(sanitized_sql) + end +end diff --git a/app/queries/get_all_id_card_data_by_plan_tpa_query.rb b/app/queries/get_all_id_card_data_by_plan_tpa_query.rb new file mode 100644 index 0000000..6f08b6a --- /dev/null +++ b/app/queries/get_all_id_card_data_by_plan_tpa_query.rb @@ -0,0 +1,94 @@ +class GetAllIDCardDataByPlanTPAQuery + + def initialize(pl_plan_key) + @pl_plan_key = ActiveRecord::Base.connection.quote(pl_plan_key) + end + + def call + VhcsRecord.connection.exec_query(sql).rows + end + + def to_id_cards_data + raw_data = call + + all_id_cards_data = [] + raw_data.each do |rd| + id_card_data = { + id: rd[0], + mb_member_key: rd[1], + mbr_type: rd[2], + division: rd[3], + full_name: rd[7], + family_id: rd[8], + mbr_class: rd[9], + effect_date: rd[11], + state: rd[12], + pl_plan_key: rd[14], + group_number: rd[15], + medical_group_num: rd[16], + dental_group_num: rd[17], + pb_product_key: rd[18], + mb_member_key: rd[19] + } + + all_id_cards_data.push(id_card_data) + end + + all_id_cards_data + end + + private + + def sql + <<~SQL + SELECT DISTINCT ROW_NUMBER() OVER(ORDER BY pbm.FamilyId ASC) as Id, pbc.MBMemberKey, + CASE WHEN div.PBENtityKey = 344215 OR div.PBENtityKey = 344217 THEN 'OSB' ELSE ou.CompanyNumber END as MbrType, + substring(div.LastName,0,41) as Div , + substring(pbe.FirstName,0,25) as MbrFirst, + substring(pbe.MiddleName,0,25) as MbrMiddle, + substring(pbe.LastName,0,50) as MbrLast, + (substring(pbe.FirstName, 0, 25) + ' ' + substring(pbe.LastName, 0, 50)) as FullName, + pbm.FamilyId, + UPPER(lct.shortdesc) as MbrClass, + 2 as MedOrDent,pp.InEffect as EffectDate, + pbea.State,ISNULL(oua.State,pbea.State) as EmpState, + M.PLPlanKey, + PC.GroupNumber, + PC.MedicalNumber, + PC.DentalNumber, + P.PBProductKey, + m.PBEntityKey as PrimaryMBMemberKey + FROM VWMBMember M INNER JOIN PBEntityClaimsData pbc on pbc.MBMemberKey=M.MBMemberKey + LEFT OUTER Join HLPlanCode PC ON PC.PlanKey = M.PLPlanKey + INNER JOIN PBMember pbm on pbm.PBEntityKey=pbc.PBEntityKey and pbm.EnrolleeTypeKey=1044 + INNER JOIN PBEntity pbe on pbe.PBEntityKey=pbm.PBEntityKey + INNER JOIN PBEntityAddress pbea on pbea.PBEntityKey=pbe.PBEntityKey and pbea.AddressTypeID=1137 + INNER JOIN PBCoveredEntities ce on ce.PBEntityKey=pbe.PBEntityKey + INNER JOIN PBProductParticipation pp on pp.PBProductParticipationKey=ce.PBProductParticipationKey + INNER JOIN (SELECT ce1.PBEntityKey, pp1.PBProductAvailabilityKey, MAX(pp1.WhenLastChanged) as WhenLastChanged, + pp1.CoverageTypeCode + FROM PBCoveredEntities ce1 + INNER JOIN PBProductParticipation pp1 on pp1.PBProductParticipationKey = ce1.PBProductParticipationKey + GROUP BY ce1.PBEntityKey, pp1.PBProductAvailabilityKey,pp1.CoverageTypeCode) + cepp ON cepp.PBEntityKey = ce.PBEntityKey AND cepp.PBProductAvailabilityKey = pp.PBProductAvailabilityKey + and cepp.CoverageTypeCode = pp.CoverageTypeCode + INNER JOIN GEN_LookupTables lct ON lct.RecordID = pp.CoverageTypeCode + INNER JOIN PBProductAvailability pa on pa.PBProductAvailabilityKey=pp.PBProductAvailabilityKey + INNER JOIN PBProduct p on p.PBProductKey=pa.PBProductKey + INNER JOIN PBAffiliation aff ON aff.PBAffiliationKey = pp.PBAffiliationKey + INNER JOIN PBEntity div on div.PBEntityKey=aff.ParentPBEntityKey + LEFT OUTER JOIN PBOrgUnit ou on ou.PBEntityKey=div.PBEntityKey + LEFT OUTER JOIN PBEntityAddress oua on oua.PBEntityKey=ou.PBEntityKey and oua.AddressTypeID=1137 WHERE p.PBProductKey in (Select DISTINCT PBProductKey From PBProduct Where FullDescription NOT LIKE '%LIFE%' AND FullDescription NOT LIKE '%VIS%') + AND pp.InEffect <= getdate() +90 + AND (pp.OutOfEffect-1 > getdate() AND + pp.OutOfEffect>pp.InEffect) + AND pp.OutOfEffect=(Select Max(Part.OutOfEffect) From PBProductParticipation Part + INNER JOIN PBProductAvailability Aval on Aval.PBProductAvailabilityKey=Part.PBProductAvailabilityKey + INNER JOIN PBProduct Prod on Prod.PBProductKey=Aval.PBProductKey + Where Prod.PBProductKey = p.PBProductKey + AND Part.PBProductParticipationKey = pp.PBProductParticipationKey) + AND M.EnrolleeTypeKey = '1044' + AND M.PLPlanKey = #{@pl_plan_key} + SQL + end +end \ No newline at end of file diff --git a/app/queries/get_id_card_data_tpa_query.rb b/app/queries/get_id_card_data_tpa_query.rb new file mode 100644 index 0000000..37ffc77 --- /dev/null +++ b/app/queries/get_id_card_data_tpa_query.rb @@ -0,0 +1,95 @@ +class GetIdCardDataTpaQuery + def initialize(family_id) + @family_id = ActiveRecord::Base.connection.quote(family_id) + if family_id.length == 9 + @entity_type = ActiveRecord::Base.connection.quote("FamilyId") + else + @entity_type = ActiveRecord::Base.connection.quote("PBEntityKey") + end + end + + def call + VhcsRecord.connection.exec_query(sql).rows.first + end + + def to_id_card_data + raw_data = call + + id_card_data = { + id: raw_data[0], + mb_member_key: raw_data[1], + mbr_type: raw_data[2], + division: raw_data[3], + full_name: raw_data[7], + family_id: raw_data[8], + mbr_class: raw_data[9], + effect_date: raw_data[11], + state: raw_data[12], + pl_plan_key: raw_data[14], + group_number: raw_data[15], + medical_group_num: raw_data[16], + dental_group_num: raw_data[17], + pb_product_key: raw_data[18], + mb_member_key: raw_data[19] + } + + [id_card_data] + end + + private + + def sql + <<~SQL + SELECT DISTINCT ROW_NUMBER() OVER(ORDER BY pbm.FamilyId ASC) as Id, pbc.MBMemberKey, + isnull(ou.CompanyNumber,'') as MbrType, + CASE WHEN m.PLPlanKey = '14' THEN 'DUPLIN COUNTY GOVERNMENT' ELSE substring(div.LastName,0,41) END as Div, + substring(pbe.FirstName,0,25) as MbrFirst, + substring(pbe.MiddleName,0,25) as MbrMiddle, + substring(pbe.LastName,0,50) as MbrLast, + (substring(pbe.FirstName, 0, 25) + ' ' + substring(pbe.LastName, 0, 50)) as FullName, + pbm.FamilyId, + UPPER(lct.shortdesc) as MbrClass, + 2 as MedOrDent, + pp.InEffect as EffectDate, + pbea.State,ISNULL(oua.State,pbea.State) as EmpState, + M.PLPlanKey, + PC.GroupNumber, + PC.MedicalNumber, + PC.DentalNumber, + P.PBProductKey, + m.PBEntityKey as PrimaryMBMemberKey + FROM VWMBMember M + INNER JOIN PBEntityClaimsData pbc on pbc.MBMemberKey=M.MBMemberKey + Inner Join HLPlanCode PC ON PC.PlanKey = M.PLPlanKey + INNER JOIN PBMember pbm on pbm.PBEntityKey=pbc.PBEntityKey and pbm.EnrolleeTypeKey=1044 + INNER JOIN PBEntity pbe on pbe.PBEntityKey=pbm.PBEntityKey + INNER JOIN PBEntityAddress pbea on pbea.PBEntityKey=pbe.PBEntityKey and pbea.AddressTypeID=1137 + INNER JOIN PBCoveredEntities ce on ce.PBEntityKey=pbe.PBEntityKey + INNER JOIN PBProductParticipation pp on pp.PBProductParticipationKey=ce.PBProductParticipationKey + INNER JOIN (SELECT ce1.PBEntityKey, pp1.PBProductAvailabilityKey, MAX(pp1.WhenLastChanged) as WhenLastChanged, + pp1.CoverageTypeCode + FROM PBCoveredEntities ce1 + INNER JOIN PBProductParticipation pp1 on pp1.PBProductParticipationKey = ce1.PBProductParticipationKey + GROUP BY ce1.PBEntityKey, pp1.PBProductAvailabilityKey,pp1.CoverageTypeCode) + cepp ON cepp.PBEntityKey = ce.PBEntityKey AND cepp.PBProductAvailabilityKey = pp.PBProductAvailabilityKey + and cepp.CoverageTypeCode = pp.CoverageTypeCode + INNER JOIN GEN_LookupTables lct ON lct.RecordID = pp.CoverageTypeCode + INNER JOIN PBProductAvailability pa on pa.PBProductAvailabilityKey=pp.PBProductAvailabilityKey + INNER JOIN PBProduct p on p.PBProductKey=pa.PBProductKey + INNER JOIN PBAffiliation aff ON aff.PBAffiliationKey = pp.PBAffiliationKey + INNER JOIN PBEntity div on div.PBEntityKey=aff.ParentPBEntityKey + LEFT OUTER JOIN PBOrgUnit ou on ou.PBEntityKey=div.PBEntityKey + LEFT OUTER JOIN PBEntityAddress oua on oua.PBEntityKey=ou.PBEntityKey and oua.AddressTypeID=1137 + WHERE p.PBProductKey in (Select PBProductKey From PBProduct Where FullDescription NOT LIKE '%LIFE%' AND FullDescription NOT LIKE '%VISION%' AND FullDescription NOT LIKE '%DENT%') + AND pp.InEffect <= getdate() +90 + AND (pp.OutOfEffect-1 > getdate() AND pp.OutOfEffect>pp.InEffect) + AND pp.OutOfEffect=(Select Max(Part.OutOfEffect) From PBProductParticipation Part + INNER JOIN PBProductAvailability Aval on Aval.PBProductAvailabilityKey=Part.PBProductAvailabilityKey + INNER JOIN PBProduct Prod on Prod.PBProductKey=Aval.PBProductKey + Where Prod.PBProductKey = p.PBProductKey + AND Part.PBProductParticipationKey = pp.PBProductParticipationKey) + AND pbm.#{@entity_type}=#{@family_id} + AND M.EnrolleeTypeKey='1044' + SQL + end +end diff --git a/app/queries/temp.rb b/app/queries/temp.rb new file mode 100644 index 0000000..e69de29 diff --git a/app/services/employer_cards/data_formatter.rb b/app/services/employer_cards/data_formatter.rb index 52f3fa1..fbd186b 100644 --- a/app/services/employer_cards/data_formatter.rb +++ b/app/services/employer_cards/data_formatter.rb @@ -6,7 +6,7 @@ module EmployerCards end def call - @members = @employer.members + @members = @employer.members.order(:name) @employer_cards = [] init_cards_and_set_member_fields @@ -19,6 +19,31 @@ module EmployerCards private + def init_cards_and_set_common_fields + employer_attributes = { + employer_name: @employer.id_card_display_name, + group_number: @employer.group_number, + rx_group: @employer.rx_group_number + } + + rx_attributes = @employer.card_rx.attributes.with_indifferent_access.slice( + :customer_service, + :web_url + ) + + provider_attributes = @employer.card_provider.attributes.with_indifferent_access.slice( + :provider_code, :provider_line_1, :provider_line_2, :provider_line_3, :provider_line_4, :provider_line_5, :provider_line_6, + :provider_line_7, :provider_line_8, :provider_line_9, :provider_line_10, :provider_line_11, :provider_line_12, + :claim_to_1, :claim_to_2, :claim_to_3, :claim_to_4, :claim_to_5, :claim_to_6, + :claim_to_7, :claim_to_8, :claim_to_9, :claim_to_10, :claim_to_11, :claim_to_12 + ) + + selected_attributes = employer_attributes.merge(rx_attributes).merge(provider_attributes) + @employer_cards.each do |card| + card.assign_attributes(selected_attributes) + end + end + def set_common_fields employer_attributes = { employer_name: @employer.id_card_display_name, @@ -32,7 +57,7 @@ module EmployerCards ) provider_attributes = @employer.card_provider.attributes.with_indifferent_access.slice( - :provider_line_1, :provider_line_2, :provider_line_3, :provider_line_4, :provider_line_5, :provider_line_6, + :provider_code, :provider_line_1, :provider_line_2, :provider_line_3, :provider_line_4, :provider_line_5, :provider_line_6, :provider_line_7, :provider_line_8, :provider_line_9, :provider_line_10, :provider_line_11, :provider_line_12, :claim_to_1, :claim_to_2, :claim_to_3, :claim_to_4, :claim_to_5, :claim_to_6, :claim_to_7, :claim_to_8, :claim_to_9, :claim_to_10, :claim_to_11, :claim_to_12 @@ -58,21 +83,29 @@ module EmployerCards end def init_cards_and_set_member_fields + @group_dependents = Vhcs::VwmbMember.where(pl_plan_key: @employer.pl_plan_key) @members.each do |me| effect_date = determine_eff_date(me) if effect_date member_card = SampleIdCard.new() - selected_attributes = { + member_attributes = { full_name: me.id_card_display_name, - primary_mb_member_key: me.mb_member_key, + name: me.name, + primary_mb_member_key: me.pb_entity_key, family_id: me.family_id, plan_id: me.plan_id, medical_eff_date: effect_date.strftime("%m/%d/%Y") - } + dependent_attributes = get_dependent_fields(me) + + selected_attributes = member_attributes.merge(dependent_attributes) member_card.assign_attributes(selected_attributes) @employer_cards.push(member_card) + + if dependent_attributes.present? + @employer_cards.push(member_card) + end end end end @@ -102,7 +135,7 @@ module EmployerCards def determine_eff_date(member) - participation = Vhcs::PbProductParticipation.joins('INNER JOIN "PBCoveredEntities" ON "PBProductParticipation"."PBProductParticipationKey" = "PBCoveredEntities"."PBProductParticipationKey"').where('"PBCoveredEntities"."PBEntityKey" = ?', member.pb_entity_key).first + participation = Vhcs::PbProductParticipation.joins('INNER JOIN "PBCoveredEntities" ON "PBProductParticipation"."PBProductParticipationKey" = "PBCoveredEntities"."PBProductParticipationKey"').where('"PBCoveredEntities"."PBEntityKey" = ?', member.pb_entity_key).last in_effect = participation.in_effect out_of_effect = participation.out_of_effect @@ -114,8 +147,14 @@ module EmployerCards end - def set_dependent_fields - # Not needed for sample card + def get_dependent_fields(member) + dependent_attributes = {} + dependents = @group_dependents.where(family_id: member.family_id).where.not(pb_entity_key: member.pb_entity_key) + dependents.each do |dep| + dependent_name = dep.first_name + ' ' + dep.last_name + dependent_attributes["dependent_#{dep.sequence_number - 1}".to_sym] = dependent_name + end + dependent_attributes end end end \ No newline at end of file diff --git a/app/services/employer_cards/jasper_url_generator.rb b/app/services/employer_cards/jasper_url_generator.rb index ae22c21..9c78fb0 100644 --- a/app/services/employer_cards/jasper_url_generator.rb +++ b/app/services/employer_cards/jasper_url_generator.rb @@ -1,17 +1,14 @@ module EmployerCards class JasperUrlGenerator - def initialize(employer, family_id) + def initialize(employer, family_id, layout) @family_id = family_id @employer = employer + @layout = layout end def call - # @net_logo = determine_network_logo - card_front_url = URI::HTTP.build(url_components("Front")) - card_back_url = URI::HTTP.build(url_components("Back")) - - [card_front_url, card_back_url] + URI::HTTP.build(url_components) end private @@ -30,17 +27,12 @@ module EmployerCards end # http://localhost:8080/trunk/PdfServlet?reportConn=BrittonConnect&id=&reportName=FairosRxSampleIDCard-Half&family_id=Classic%202K&employer_logo=BryanPestControl.jpeg&network_logo=CignaLogo.png&reportDir=secure/Documents&SUBREPORT_DIR=/&ImageDir=secure/Documents&netToken=3a4a8b03f4dfb0e6e3fc82dd369f70ef&FileType=PDF # http://localhost:8080/trunk/PdfServlet?reportConn=BrittonConnect&id=&reportName=FairosRxSampleIDCard-Half&family_id=Classic%202K&employer_logo=BryanPestControl.jpeg&network_logo=CignaLogo.png&reportDir=secure/Documents&SUBREPORT_DIR=/&ImageDir=secure/Documents&netToken=3a4a8b03f4dfb0e6e3fc82dd369f70ef&FileType=PDF - def url_components(card_side) - if card_side == "Back" && @employer.single_card_template.include?("-Half") - template = @employer.single_card_template.gsub("-Half", "") - else - template = @employer.single_card_template - end + def url_components { host: '10.41.1.115', port: 8080, - path: '/trunk/PdfServlet', - query: "reportConn=BrittonConnect&id=&reportName=#{template}-#{card_side}-Print&family_id=#{@family_id}&employer_logo=#{@employer.employer_logo_filename}&network_logo=#{determine_network_logo}&reportDir=secure/Documents&SUBREPORT_DIR=/&ImageDir=secure/Documents&netToken=3a4a8b03f4dfb0e6e3fc82dd369f70ef&FileType=PDF" + path: '/trunk/IdCardsServlet', + query: "reportConn=BrittonConnect&cardTemplate=#{@employer.single_card_template}&printType=#{@layout}&family_id=#{@family_id }&employer_logo=#{@employer.employer_logo_filename}&network_logo=#{determine_network_logo}&FileType=PDF" } end diff --git a/app/services/employer_cards_generator.rb b/app/services/employer_cards_generator.rb index 617cbc3..2b7d5a0 100644 --- a/app/services/employer_cards_generator.rb +++ b/app/services/employer_cards_generator.rb @@ -1,22 +1,47 @@ class EmployerCardsGenerator - def initialize(employer) + def initialize(employer, layout) @employer = employer + @layout = layout end def call SampleIdCard.where(employer_name: @employer.id_card_display_name).destroy_all EmployerCards::DataFormatter.new(@employer).call - group_cards_pdf = CombinePDF.new - SampleIdCard.where(employer_name: @employer.id_card_display_name).each do |card| - urls = EmployerCards::JasperUrlGenerator.new(@employer, card.family_id).call - puts urls - card_front_pdf = SampleCard::JasperPdfGenerator.new(urls.first).call - card_back_pdf = SampleCard::JasperPdfGenerator.new(urls.last).call + if @layout == "FullPageCard" + group_cards_pdf_array = [] + reprint = Vhcs::HlidCardEggData.where(group_number: @employer.group_number).pluck(:family_id) + SampleIdCard.where(employer_name: @employer.id_card_display_name).each do |card| + if reprint.include?(card.family_id) + url = EmployerCards::JasperUrlGenerator.new(@employer, card.family_id, @layout).call + puts url + card_pdf = SampleCard::JasperPdfGenerator.new(url).call + card_filename = "#{card.name.gsub(", ","_")}_digital_card_#{Date.today}.pdf" + # group_cards_pdf_array.add(card_filename, pdf_object.to_pdf) + group_cards_pdf_array << { name: card_filename, data: card_pdf.to_pdf } + end + end - group_cards_pdf << card_front_pdf - group_cards_pdf << card_back_pdf + # Initialize a string-based IO object + group_cards_pdf = Zip::OutputStream.write_buffer do |zio| + group_cards_pdf_array.each do |file| + zio.put_next_entry(file[:name]) + zio.write(file[:data]) + end + end + else + group_cards_pdf = CombinePDF.new + reprint = Vhcs::HlidCardEggData.where(group_number: @employer.group_number).pluck(:family_id) + SampleIdCard.where(employer_name: @employer.id_card_display_name).each do |card| + if reprint.include?(card.family_id) + url = EmployerCards::JasperUrlGenerator.new(@employer, card.family_id, @layout).call + puts url + card_pdf = SampleCard::JasperPdfGenerator.new(url).call + + group_cards_pdf << card_pdf + end + end end # todays_date = DateTime.current.strftime('%Y%m%d%H%M%S') diff --git a/app/services/sample_card/data_formatter.rb b/app/services/sample_card/data_formatter.rb index 648043f..439d449 100644 --- a/app/services/sample_card/data_formatter.rb +++ b/app/services/sample_card/data_formatter.rb @@ -12,6 +12,7 @@ module SampleCard set_generic_fields() set_rx_fields() set_network_fields() + # set_dependent_fields() sample_cards = set_plan_fields() sample_cards.each(&:save!) @@ -33,7 +34,8 @@ module SampleCard plans_sample_cards = [] @employer.plans.each do |plan| plan_sample_card = @sample_card.dup - plan_sample_card.family_id = plan.title + plan_name = plan.title.split(/(?<=\d[kK])/).first + plan_sample_card.family_id = plan_name plan.plan_benefits.each do |bene| plan_sample_card["benefit_desc_#{bene.sequence}".to_sym] = bene.benefit_desc plan_sample_card["benefit_#{bene.sequence}".to_sym] = bene.benefit @@ -60,6 +62,9 @@ module SampleCard :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 ) + if @employer.network_provider == "Cigna" + @sample_card.provider_code = "5" + end @sample_card.assign_attributes(selected_attributes) end @@ -75,7 +80,14 @@ module SampleCard end def set_dependent_fields - # Not needed for sample card + @sample_card.dependent_1 = "John Doe" + @sample_card.dependent_2 = "Molly Doe" + @sample_card.dependent_3 = "Jonathan Doe" + @sample_card.dependent_4 = "Calvin Doe" + @sample_card.dependent_5 = "Richard Doe" + @sample_card.dependent_6 = "Jannet Doe" + @sample_card.dependent_7 = "Longername Doe" + @sample_card.dependent_8 = "Robbert Doe" end end end \ No newline at end of file diff --git a/app/services/sample_card/jasper_url_generator.rb b/app/services/sample_card/jasper_url_generator.rb index 9ce88c7..21fd304 100644 --- a/app/services/sample_card/jasper_url_generator.rb +++ b/app/services/sample_card/jasper_url_generator.rb @@ -24,11 +24,11 @@ module SampleCard # end # end # @network_logos.find_by(default: true).net_logo - if @employer.single_card_template.include?("Half") - "FairosRxSampleIDCard-Half-Display" - else - "FairosRxSampleIDCard-Display" - end + # if @employer.single_card_template.include?("Half") + # "FairosRxSampleIDCard-Half-Display" + # else + # "FairosRxSampleIDCard-Display" + # end end def determine_network_logo @@ -49,8 +49,8 @@ module SampleCard { host: '10.41.1.115', port: 8080, - path: '/trunk/PdfServlet', - query: "reportConn=BrittonConnect&id=&reportName=#{determine_card_template}&family_id=#{@plan_name}&employer_logo=#{@employer.employer_logo_filename}&network_logo=#{determine_network_logo}&reportDir=secure/Documents&SUBREPORT_DIR=/&ImageDir=secure/Documents&netToken=3a4a8b03f4dfb0e6e3fc82dd369f70ef&FileType=PDF" + path: '/trunk/IdCardsServlet', + query: "reportConn=BrittonConnect&cardTemplate=FairosRxIDCard&printType=SampleCard&family_id=#{@plan_name}&employer_logo=#{@employer.employer_logo_filename}&network_logo=#{determine_network_logo}&FileType=PDF" } end diff --git a/app/services/sample_card/pdf_printer.rb b/app/services/sample_card/pdf_printer.rb index 16a1a15..a8ee2c0 100644 --- a/app/services/sample_card/pdf_printer.rb +++ b/app/services/sample_card/pdf_printer.rb @@ -17,7 +17,7 @@ module SampleCard end employer_name = @process.employer_name.downcase.tr(" ", "_") - todays_date = Date.today.strftime("%m-%d-%Y") + todays_date = Date.today.strftime("%m/%d/%Y") group_cards_pdf.save("tmp/#{employer_name}_sample_cards_#{todays_date}.pdf") group_cards_pdf diff --git a/app/views/employer_setup/edit.html.erb b/app/views/employer_setup/edit.html.erb index be5ed88..40d73c5 100644 --- a/app/views/employer_setup/edit.html.erb +++ b/app/views/employer_setup/edit.html.erb @@ -10,7 +10,7 @@
- <%= f.text_field :employer_name, label: { text: "Employer Name" }, data: { logo_upload_target: "initialLogoFile" }, class: "w-full" %> + <%= f.text_field :employer_name, label: { text: "Employer Name" }, class: "w-full" %>
<%= f.text_field :slug, label: { text: "Slug" }, class: "w-full" %> diff --git a/app/views/employers/_alt_network_logo_fields_new.html.erb b/app/views/employers/_alt_network_logo_fields_new.html.erb new file mode 100644 index 0000000..b37cef5 --- /dev/null +++ b/app/views/employers/_alt_network_logo_fields_new.html.erb @@ -0,0 +1,15 @@ + + diff --git a/app/views/employers/edit.html.erb b/app/views/employers/edit.html.erb index 9249e23..29d520b 100644 --- a/app/views/employers/edit.html.erb +++ b/app/views/employers/edit.html.erb @@ -118,8 +118,9 @@ <% end %>
-
+
<%= f.submit "Submit" %> + <%= link_to "Back", employer_path(@employer.slug), class: "flex justify-center items-center cursor-pointer bg-atmosphere hover:bg-deepcove border-2 border-atmosphere text-platinum font-bold px-3 rounded-sm h-10 transition duration-100" %>
<% end %> diff --git a/app/views/employers/index.html.erb b/app/views/employers/index.html.erb index 0171c62..e1e1f55 100644 --- a/app/views/employers/index.html.erb +++ b/app/views/employers/index.html.erb @@ -1,21 +1,33 @@
-

Employers

- <% plan_colors = EmployerSetupPlansForm::PLAN_COLORS.push('copper', 'bronze').shuffle %> -

In Process:

- <% @employers.inactive.each_with_index do |es, index| %> - <% item_color_index = index == 0 ? 0 : index % plan_colors.length %> -
"> - <%= link_to es.name, employer_path(es.slug), class: "hover:text-atmosphere" %> -
- <% end %> -
- <%= link_to "New Employer", new_employer_path, class: "hover:text-verdigris" %> +
+

Employers

+ <%= link_to new_employer_path, class: "flex justify-center items-center h-8 w-8 ml-2 mb-6 text-sm text-bronze bg-deepcove hover:bg-cobalt font-semibold p-1 rounded-lg border-2 border-cobalt" do %> + <%= icon "clipboard-plus", library: "lucide" %> + <% end %> +
-

Live:

- <% @employers.active.each_with_index do |es, index| %> - <% item_color_index = index == 0 ? 0 : index % plan_colors.length %> -
"> - <%= link_to es.name, employer_path(es.slug), class: "hover:text-atmosphere" %> + <% plan_colors = EmployerSetupPlansForm::PLAN_COLORS.push('copper', 'bronze').shuffle %> + <% @color_index = 0 %> +

In Process:

+ <% @employers.inactive.each_with_index do |emp, index| %> + <% item_color_index = @color_index == 0 ? 0 : @color_index % plan_colors.length %> +
"> + <%= link_to emp.name, employer_path(emp.slug), class: "hover:text-#{plan_colors[item_color_index]}" %> +
+ <%= "(Effective #{emp.effective_date})" %> +
+ <% @color_index += 1 %> + <% end %> +

Live:

+ <% @employers.active.each_with_index do |emp, index| %> + <% item_color_index = @color_index == 0 ? 0 : @color_index % plan_colors.length %> +
"> + <%= link_to emp.name, employer_path(emp.slug), class: "hover:text-#{plan_colors[item_color_index]}" %> +
+ <%= "(#{emp.members.count} Members)" %> +
+
+ <% @color_index += 1 %> <% end %>
\ No newline at end of file diff --git a/app/views/employers/new_new.html.erb b/app/views/employers/new_new.html.erb new file mode 100644 index 0000000..f15a818 --- /dev/null +++ b/app/views/employers/new_new.html.erb @@ -0,0 +1,170 @@ +
+
+

New Employer

+ <%= form_with model: @employer, url: import_employers_path, data: { turbo: false }, local: true, multipart: true do |form| %> +
+
+ <%= form.label :import_from_word, 'ID Card Setup Word Doc', class: "block text-platinum font-bold mb-1 md:mb-0 pr-4" %> + <%= form.file_field :import_from_word %> +
+ <%= form.submit "Import", class: "h-[40px]" %> +
+ <% end %> +
+ <%= form_with model: @employer, local: true, multipart: true do |f| %> +
+
+

General Information

+
+
+
+
+
+
+ <%= f.text_field :name, label: { text: "Employer Name" }, data: { logo_upload_target: "employer" }, class: "w-full" %> +
+
+ <%= f.text_field :group_number, label: { text: "Group/Medical Number" }, class: "w-full" %> +
+
+
+
+ <%= f.text_field :effective_date, label: { text: "Effective Date" }, class: "w-full" %> +
+
+ <%= f.select :network_provider, options_for_select(["Cigna", "Medcost"]), label: { text: "Provider Network" }, data: { logo_upload_target: "network" }, class: "w-full" %> + <%= f.hidden_field :single_card_template, value: @employer.single_card_template %> + <%= f.hidden_field :default_network_logo, value: @employer.default_network_logo %> + <%= f.hidden_field :card_provider_id, value: @employer.card_provider_id %> + <%= f.hidden_field :card_rx_id, value: @employer.card_rx_id %> +
+
+
+
+
+ <%= f.text_field :employer_logo_filename, label: { text: "Employer Logo" }, default: "No logo added", data: { logo_upload_target: "logofield" }, class: "w-full rounded-r-none", readonly: true %> +
+
+ +
+
+ + <%= f.file_field :add_or_update_logo, class: "hidden", id: "file_upload_input_employer", data: { logo_upload_target: "previewContainer", logo_upload_type_param: "employer", action: "change->logo-upload#uploadLogo" }, direct_upload: true %> +
+
+
+
+

Plans Information

+
+
+
+
+ <% @employer.plans.each_with_index do |plan, index| %> + <%= f.fields_for :plans, plan, child_index: index do |plan_fields| %> +
+
">
+
-ml-[6px] z-2 w-full"> + <%= "Plan #{index + 1}" %> +
+ <%= render 'plan_fields', plan_fields: plan_fields, f: f, index: index %> +
"> + Benefit Values +
+
ml-[3px]">
+ <%= plan_fields.fields_for :plan_benefits do |plan_benefits_fields| %> + <%= render 'plan_benefits_fields', plan_benefits_fields: plan_benefits_fields %> + <% end %> +
+ <%= plan_fields.hidden_field :_destroy %> + <%= button_tag "Remove Plan #{index + 1}", class: "cursor-pointer bg-deepcove hover:bg-brightlava text-xl font-bold text-copper hover:text-platinum py-2 px-4 font-semibold leading-tight rounded-lg border-3 border-copper w-full", data: { action: "add-plan#remove" } %> +
+
+ <% end %> + <% end %> + <%= button_tag "Add a Plan", class: "cursor-pointer text-2xl font-bold py-2 pr-6 mt-10 w-[calc(24%-1rem)] w-1/4 min-h-[940px] text-[#E0E0E0] rounded-lg font-medium border border-[#E0E0E0] bg-[#173057] hover:bg-transparent hover:shadow-[0_0_10px_3px_#93c5fd] transition-colors duration-150", data: { action: "add-plan#add", add_plan_target: "button" } %> +
+ +
+
+ +
+

ID Card Exceptions Information

+
+
+
+ <%= button_tag "Add an Exception", class: "cursor-pointer text-lg font-medium py-2 px-4 rounded w-1/7 h-35 my-8 text-[#E0E0E0] rounded-lg border border-[#C2C2C2] hover:shadow-[0_0_10px_3px_#93c5fd]", data: { action: "add-exception#addExemption", add_exception_target: "exceptionButton" } %> + +
+
+ <%= f.submit "Submit" %> +
+
+ <% end %> +
diff --git a/app/views/employers/show.html.erb b/app/views/employers/show.html.erb index dbc99f4..2893391 100644 --- a/app/views/employers/show.html.erb +++ b/app/views/employers/show.html.erb @@ -25,17 +25,21 @@
<% @employer.attributes.with_indifferent_access.slice(:pl_plan_key, :company_pb_entity_key, :group_number).each do |attribute_name, attribute_value| %>

"> - ├── <%= attribute_name.humanize %>: + ├── <%= attribute_name.titleize %>: <%= attribute_value.present? ? attribute_value.to_s : "waiting" %>

<% end %>
└── Plans
- <% @employer.plans.pluck(:title).each do |plan_title| %> + <% @employer.plans.pluck(:title, :pb_product_key).each do |plan| %>
- ├── <%= plan_title %> + ├── <%= plan.first %>
+

"> + └── PB Product Key: + <%= plan.last.present? ? plan.last.to_s : "waiting" %> +

<% end %>
@@ -51,8 +55,8 @@
<%= link_to 'Generate Sample Cards', generate_sample_sample_id_cards_path(employer_slug: @employer.slug ), data: { turbo: false }, class: "flex justify-center items-center w-2/3 cursor-pointer bg-atmosphere hover:bg-deepcove border-2 border-atmosphere text-platinum font-bold px-3 rounded-lg h-10 transition duration-100" %> <%= link_to 'Generate Group Cards (for print)', generate_print_sample_id_cards_path(employer_slug: @employer.slug ),data: { turbo: false }, class: "flex justify-center items-center w-2/3 #{@employer.active ? "" : "pointer-events-none opacity-50 cursor-not-allowed"} bg-atmosphere hover:bg-deepcove border-2 border-atmosphere text-platinum font-bold px-3 rounded-lg h-10 transition duration-100" %> - <%= link_to 'Generate Group Cards (for display)', generate_sample_sample_id_cards_path(employer_slug: @employer.slug ), data: { turbo: false }, class: "flex justify-center items-center w-2/3 pointer-events-none opacity-50 cursor-not-allowed bg-atmosphere hover:bg-deepcove border-2 border-atmosphere text-platinum font-bold px-3 rounded-lg h-10 transition duration-100" %> - <%= link_to 'Generate Group Cards (for download)', generate_sample_sample_id_cards_path(employer_slug: @employer.slug ), data: { turbo: false }, class: "flex justify-center items-center w-2/3 pointer-events-none opacity-50 cursor-not-allowed bg-atmosphere hover:bg-deepcove border-2 border-atmosphere text-platinum font-bold px-3 rounded-lg h-10 transition duration-100" %> + <%= link_to 'Generate Group Cards (for display)', generate_mobile_display_sample_id_cards_path(employer_slug: @employer.slug ), data: { turbo: false }, class: "flex justify-center items-center w-2/3 #{@employer.active ? "" : "pointer-events-none opacity-50 cursor-not-allowed"} bg-atmosphere hover:bg-deepcove border-2 border-atmosphere text-platinum font-bold px-3 rounded-lg h-10 transition duration-100" %> + <%= link_to 'Generate Group Cards (for download)', generate_full_page_sample_id_cards_path(employer_slug: @employer.slug ), data: { turbo: false }, class: "flex justify-center items-center w-2/3 #{@employer.active ? "" : "pointer-events-none opacity-50 cursor-not-allowed"} bg-atmosphere hover:bg-deepcove border-2 border-atmosphere text-platinum font-bold px-3 rounded-lg h-10 transition duration-100" %>
\ No newline at end of file diff --git a/app/views/welcome/tailwind_colors.html.erb b/app/views/welcome/tailwind_colors.html.erb index 37e5d80..168ecc9 100644 --- a/app/views/welcome/tailwind_colors.html.erb +++ b/app/views/welcome/tailwind_colors.html.erb @@ -1,9 +1,9 @@ -
co
-
co
-
co
-
co
-
co
-
co
+
co
+
co
+
co
+
co
+
co
+
co
co
co
co
diff --git a/compose.yaml b/compose.yaml index 5ee3deb..3862076 100644 --- a/compose.yaml +++ b/compose.yaml @@ -17,30 +17,30 @@ services: - TAILWIND_POLLING=true tty: true stdin_open: true - depends_on: - db: - condition: service_healthy - redis: - condition: service_started - db: - build: - context: . - dockerfile: Dockerfile.db - volumes: - - ./mssql-data:/var/opt/mssql - ports: - - "1434:1434" - healthcheck: - test: ["CMD", "/opt/mssql-tools/bin/sqlcmd", "-Usa", "-PBr1tt0nPassw0rd", "-Q", "select 1"] - interval: 10s - timeout: 3s - retries: 10 - start_period: 10s - redis: - image: redis - volumes: - - redis_data:/data + # depends_on: + # db: + # condition: service_healthy + # redis: + # condition: service_started + # db: + # build: + # context: . + # dockerfile: Dockerfile.db + # volumes: + # - ./mssql-data:/var/opt/mssql + # ports: + # - "1434:1434" + # healthcheck: + # test: ["CMD", "/opt/mssql-tools/bin/sqlcmd", "-Usa", "-PBr1tt0nPassw0rd", "-Q", "select 1"] + # interval: 10s + # timeout: 3s + # retries: 10 + # start_period: 10s + # redis: + # image: redis + # volumes: + # - redis_data:/data volumes: - redis_data: + # redis_data: bundle: diff --git a/config/database.yml b/config/database.yml index ab607a7..724021d 100644 --- a/config/database.yml +++ b/config/database.yml @@ -34,8 +34,8 @@ development: tds_version: 7.3 vhcs: <<: *default - # host: 10.41.82.72 #Prod - host: 10.41.82.73 #Dev + host: 10.41.82.72 #Prod + # host: 10.41.82.73 #Dev port: 1433 database: VHCS_HIPAA username: BSTI diff --git a/config/puma.rb b/config/puma.rb index 2620821..17feadd 100644 --- a/config/puma.rb +++ b/config/puma.rb @@ -29,7 +29,7 @@ port ENV.fetch("PORT", 3002) # Allow puma to be restarted by `bin/rails restart` command. plugin :tmp_restart -plugin :tailwindcss +# plugin :tailwindcss # Only use a pidfile when requested pidfile ENV["PIDFILE"] if ENV["PIDFILE"] diff --git a/config/routes.rb b/config/routes.rb index 2e5e28e..53cfe3e 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -17,6 +17,8 @@ Rails.application.routes.draw do collection do get 'generate_sample' get 'generate_print' + get 'generate_mobile_display' + get 'generate_full_page' end end diff --git a/db/migrate/20260116181849_create_card_exceptions.rb b/db/migrate/20260116181849_create_card_exceptions.rb new file mode 100644 index 0000000..dcca654 --- /dev/null +++ b/db/migrate/20260116181849_create_card_exceptions.rb @@ -0,0 +1,11 @@ +class CreateCardExceptions < ActiveRecord::Migration[7.2] + def change + create_table :card_exceptions do |t| + t.string :type + t.string :value + t.belongs_to :employer, null: false, foreign_key: true + + t.timestamps + end + end +end diff --git a/db/migrate/20260116182836_create_card_exception_items.rb b/db/migrate/20260116182836_create_card_exception_items.rb new file mode 100644 index 0000000..b830c78 --- /dev/null +++ b/db/migrate/20260116182836_create_card_exception_items.rb @@ -0,0 +1,13 @@ +class CreateCardExceptionItems < ActiveRecord::Migration[7.2] + def change + create_table :card_exception_items do |t| + t.string :field_name + t.string :field_value + t.belongs_to :card_exception, null: false, foreign_key: true + t.belongs_to :card_logo_file, null: true, foreign_key: true + t.belongs_to :card_provider, null: true, foreign_key: true + + t.timestamps + end + end +end diff --git a/db/migrate/20260206202113_add_aspect_ratio_to_card_logo_files.rb b/db/migrate/20260206202113_add_aspect_ratio_to_card_logo_files.rb new file mode 100644 index 0000000..c40a647 --- /dev/null +++ b/db/migrate/20260206202113_add_aspect_ratio_to_card_logo_files.rb @@ -0,0 +1,5 @@ +class AddAspectRatioToCardLogoFiles < ActiveRecord::Migration[7.2] + def change + add_column :card_logo_files, :aspect_ratio, :float + end +end diff --git a/db/migrate/20260223223545_add_last_name_to_sample_id_card.rb b/db/migrate/20260223223545_add_last_name_to_sample_id_card.rb new file mode 100644 index 0000000..5659ade --- /dev/null +++ b/db/migrate/20260223223545_add_last_name_to_sample_id_card.rb @@ -0,0 +1,5 @@ +class AddLastNameToSampleIdCard < ActiveRecord::Migration[7.2] + def change + add_column :sample_id_cards, :name, :string + end +end diff --git a/db/migrate/20260227192437_rename_card_field_exceptions_to_card_exception_items.rb b/db/migrate/20260227192437_rename_card_field_exceptions_to_card_exception_items.rb new file mode 100644 index 0000000..5bee1e2 --- /dev/null +++ b/db/migrate/20260227192437_rename_card_field_exceptions_to_card_exception_items.rb @@ -0,0 +1,5 @@ +class RenameCardFieldExceptionsToCardExceptionItems < ActiveRecord::Migration[7.2] + def change + rename_table :card_field_exceptions, :card_exception_items + end +end diff --git a/db/migrate/20260227213305_add_title_to_card_providers.rb b/db/migrate/20260227213305_add_title_to_card_providers.rb new file mode 100644 index 0000000..0fcb52f --- /dev/null +++ b/db/migrate/20260227213305_add_title_to_card_providers.rb @@ -0,0 +1,5 @@ +class AddTitleToCardProviders < ActiveRecord::Migration[7.2] + def change + add_column :card_providers, :title, :string + end +end diff --git a/db/migrate/20251203143745_add_network_provider_to_employer_setup_processes.rb b/db/old/20251203143745_add_network_provider_to_employer_setup_processes.rb similarity index 100% rename from db/migrate/20251203143745_add_network_provider_to_employer_setup_processes.rb rename to db/old/20251203143745_add_network_provider_to_employer_setup_processes.rb diff --git a/db/migrate/20251204151226_add_network_logo_to_employer_setup_processes.rb b/db/old/20251204151226_add_network_logo_to_employer_setup_processes.rb similarity index 100% rename from db/migrate/20251204151226_add_network_logo_to_employer_setup_processes.rb rename to db/old/20251204151226_add_network_logo_to_employer_setup_processes.rb diff --git a/db/migrate/20251204151452_rename_logo_filename_on_employer_setup_processes.rb b/db/old/20251204151452_rename_logo_filename_on_employer_setup_processes.rb similarity index 100% rename from db/migrate/20251204151452_rename_logo_filename_on_employer_setup_processes.rb rename to db/old/20251204151452_rename_logo_filename_on_employer_setup_processes.rb diff --git a/db/migrate/20251205150421_add_pl_plan_key_to_employer_setup_processes.rb b/db/old/20251205150421_add_pl_plan_key_to_employer_setup_processes.rb similarity index 100% rename from db/migrate/20251205150421_add_pl_plan_key_to_employer_setup_processes.rb rename to db/old/20251205150421_add_pl_plan_key_to_employer_setup_processes.rb diff --git a/db/migrate/20251205215553_add_plan_id_to_plan.rb b/db/old/20251205215553_add_plan_id_to_plan.rb similarity index 100% rename from db/migrate/20251205215553_add_plan_id_to_plan.rb rename to db/old/20251205215553_add_plan_id_to_plan.rb diff --git a/db/migrate/20251209182135_add_employer_set_up_process_to_card_logo_files.rb b/db/old/20251209182135_add_employer_set_up_process_to_card_logo_files.rb similarity index 100% rename from db/migrate/20251209182135_add_employer_set_up_process_to_card_logo_files.rb rename to db/old/20251209182135_add_employer_set_up_process_to_card_logo_files.rb diff --git a/db/old/20251210202210_allow_null_es_pon_card_logo_files.rb b/db/old/20251210202210_allow_null_es_pon_card_logo_files.rb new file mode 100644 index 0000000..ac2d84a --- /dev/null +++ b/db/old/20251210202210_allow_null_es_pon_card_logo_files.rb @@ -0,0 +1,5 @@ +class AllowNullEsPonCardLogoFiles < ActiveRecord::Migration[7.2] + def change + change_column_null :card_logo_files, :employer_setup_process_id, true + end +end diff --git a/db/old/20251225054626_change_mb_member_key_to_string.rb b/db/old/20251225054626_change_mb_member_key_to_string.rb new file mode 100644 index 0000000..f7ffa4a --- /dev/null +++ b/db/old/20251225054626_change_mb_member_key_to_string.rb @@ -0,0 +1,5 @@ +class ChangeMbMemberKeyToString < ActiveRecord::Migration[7.2] + def change + change_column :sample_id_cards, :primary_mb_member_key, :string + end +end diff --git a/db/old/20260107143335_rename_employer_setup_process_to_employer.rb b/db/old/20260107143335_rename_employer_setup_process_to_employer.rb new file mode 100644 index 0000000..ce0c929 --- /dev/null +++ b/db/old/20260107143335_rename_employer_setup_process_to_employer.rb @@ -0,0 +1,5 @@ +class RenameEmployerSetupProcessToEmployer < ActiveRecord::Migration[7.2] + def change + rename_table :employer_setup_processes, :employers + end +end diff --git a/db/old/20260107143914_update_fields_on_employer.rb b/db/old/20260107143914_update_fields_on_employer.rb new file mode 100644 index 0000000..bd41540 --- /dev/null +++ b/db/old/20260107143914_update_fields_on_employer.rb @@ -0,0 +1,14 @@ +class UpdateFieldsOnEmployer < ActiveRecord::Migration[7.2] + def change + remove_column :employers, :form_method, :string + remove_column :employers, :status, :string + remove_column :employers, :current_step, :string + remove_column :employers, :applied_to_prod, :boolean + remove_column :employers, :applied_to_dev, :boolean + rename_column :employers, :employer_name, :name + rename_column :employers, :card_template, :single_card_template + add_column :employers, :multiple_card_template, :string + add_column :employers, :plan_id, :integer + add_column :employers, :active, :boolean, default: false + end +end diff --git a/db/old/20260107154720_update_belongs_to_key_for_employer.rb b/db/old/20260107154720_update_belongs_to_key_for_employer.rb new file mode 100644 index 0000000..d72795f --- /dev/null +++ b/db/old/20260107154720_update_belongs_to_key_for_employer.rb @@ -0,0 +1,7 @@ +class UpdateBelongsToKeyForEmployer < ActiveRecord::Migration[7.2] + def change + rename_column :alternate_network_logos, :employer_setup_process_id, :employer_id + rename_column :card_logo_files, :employer_setup_process_id, :employer_id + rename_column :plans, :employer_setup_process_id, :employer_id + end +end diff --git a/db/old/20260107173606_add_pb_entity_key_to_employer.rb b/db/old/20260107173606_add_pb_entity_key_to_employer.rb new file mode 100644 index 0000000..786c611 --- /dev/null +++ b/db/old/20260107173606_add_pb_entity_key_to_employer.rb @@ -0,0 +1,5 @@ +class AddPbEntityKeyToEmployer < ActiveRecord::Migration[7.2] + def change + add_column :employers, :company_pb_entity_key, :integer + end +end diff --git a/db/old/20260107181416_add_image_type_to_employer_images.rb b/db/old/20260107181416_add_image_type_to_employer_images.rb new file mode 100644 index 0000000..ffbf54e --- /dev/null +++ b/db/old/20260107181416_add_image_type_to_employer_images.rb @@ -0,0 +1,5 @@ +class AddImageTypeToEmployerImages < ActiveRecord::Migration[7.2] + def change + add_column :employer_images, :image_type, :string + end +end diff --git a/db/old/20260113150100_add_card_provider_to_employers.rb b/db/old/20260113150100_add_card_provider_to_employers.rb new file mode 100644 index 0000000..38328b9 --- /dev/null +++ b/db/old/20260113150100_add_card_provider_to_employers.rb @@ -0,0 +1,5 @@ +class AddCardProviderToEmployers < ActiveRecord::Migration[7.2] + def change + add_reference :employers, :card_provider, null: true, foreign_key: true + end +end diff --git a/db/old/20260113165019_add_provder_line_and_claim_to12_to_sample_id_cards.rb b/db/old/20260113165019_add_provder_line_and_claim_to12_to_sample_id_cards.rb new file mode 100644 index 0000000..239ab57 --- /dev/null +++ b/db/old/20260113165019_add_provder_line_and_claim_to12_to_sample_id_cards.rb @@ -0,0 +1,6 @@ +class AddProvderLineAndClaimTo12ToSampleIdCards < ActiveRecord::Migration[7.2] + def change + add_column :sample_id_cards, :provider_line_12, :string + add_column :sample_id_cards, :claim_to_12, :string + end +end diff --git a/db/old/20260114184154_add_id_card_fields_to_employer.rb b/db/old/20260114184154_add_id_card_fields_to_employer.rb new file mode 100644 index 0000000..c1a0304 --- /dev/null +++ b/db/old/20260114184154_add_id_card_fields_to_employer.rb @@ -0,0 +1,5 @@ +class AddIdCardFieldsToEmployer < ActiveRecord::Migration[7.2] + def change + add_column :employers, :id_card_display_name, :string + end +end diff --git a/db/old/20260114205055_add_plan_id_to_member.rb b/db/old/20260114205055_add_plan_id_to_member.rb new file mode 100644 index 0000000..222b6a9 --- /dev/null +++ b/db/old/20260114205055_add_plan_id_to_member.rb @@ -0,0 +1,5 @@ +class AddPlanIdToMember < ActiveRecord::Migration[7.2] + def change + add_reference :members, :plans, null: true, foreign_key: true + end +end diff --git a/db/schema.rb b/db/schema.rb index e6f7ba1..0e20515 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema[7.2].define(version: 2026_01_14_183848) do +ActiveRecord::Schema[7.2].define(version: 2026_02_27_213305) do create_table "action_text_rich_texts", force: :cascade do |t| t.string "name", null: false t.text "body" @@ -59,6 +59,26 @@ ActiveRecord::Schema[7.2].define(version: 2026_01_14_183848) do t.index ["employer_id"], name: "index_alternate_network_logos_on_employer_id" end + create_table "card_exception_items", force: :cascade do |t| + t.string "field_name" + t.string "field_value" + t.bigint "card_logo_file_id" + t.bigint "card_provider_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["card_logo_file_id"], name: "index_card_exception_items_on_card_logo_file_id" + t.index ["card_provider_id"], name: "index_card_exception_items_on_card_provider_id" + end + + create_table "card_exceptions", force: :cascade do |t| + t.string "type" + t.string "value" + t.bigint "employer_id", null: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["employer_id"], name: "index_card_exceptions_on_employer_id" + end + create_table "card_logo_files", force: :cascade do |t| t.string "filename" t.binary "image_data" @@ -67,6 +87,7 @@ ActiveRecord::Schema[7.2].define(version: 2026_01_14_183848) do t.boolean "active", default: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.float "aspect_ratio" end create_table "card_providers", force: :cascade do |t| @@ -113,6 +134,7 @@ ActiveRecord::Schema[7.2].define(version: 2026_01_14_183848) do t.string "precert_6" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.string "title" end create_table "card_rxes", force: :cascade do |t| @@ -281,11 +303,15 @@ ActiveRecord::Schema[7.2].define(version: 2026_01_14_183848) do t.string "benefit_14" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.string "name" end add_foreign_key "active_storage_attachments", "active_storage_blobs", column: "blob_id" add_foreign_key "active_storage_variant_records", "active_storage_blobs", column: "blob_id" add_foreign_key "alternate_network_logos", "employers" + add_foreign_key "card_exception_items", "card_logo_files" + add_foreign_key "card_exception_items", "card_providers" + add_foreign_key "card_exceptions", "employers" add_foreign_key "employer_card_logos", "card_logo_files" add_foreign_key "employer_card_logos", "employers" add_foreign_key "employers", "card_providers" diff --git a/db/seeds.rb b/db/seeds.rb index 5130bef..e8c50c8 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -83,30 +83,30 @@ def determine_network_logos(pl_plan_key) end end -benefit_descriptions = ["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"] +# benefit_descriptions = ["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"] -default = IdCardBenefitsTemplate.create(title: "BLANK") -benefit_descriptions.each_with_index do |bene, i| - IdCardBenefit.create(sequence: i + 1, benefit_desc: bene, id_card_benefits_template: default) -end +# default = IdCardBenefitsTemplate.create(title: "BLANK") +# benefit_descriptions.each_with_index do |bene, i| +# IdCardBenefit.create(sequence: i + 1, benefit_desc: bene, id_card_benefits_template: default) +# end -temp_2 = IdCardBenefitsTemplate.create(title: "Jason's Template") -(1..14).each do |seq| - IdCardBenefit.create(sequence: seq, benefit: "#{seq} hit wonder", id_card_benefits_template: temp_2) -end +# temp_2 = IdCardBenefitsTemplate.create(title: "Jason's Template") +# (1..14).each do |seq| +# IdCardBenefit.create(sequence: seq, benefit: "#{seq} hit wonder", id_card_benefits_template: temp_2) +# end # temp_1 = IdCardBenefitsTemplate.create(title: "Rebekah's Template") # (1..14).each do |seq| @@ -130,7 +130,7 @@ end # Imports employers and members from VHCS -sql_query = "SELECT PLPlanKey, PlanId, ShortDesc FROM PLPlanHeader WHERE ActiveInactive = 'Active' AND PLPlanKey = 61" +sql_query = "SELECT PLPlanKey, PlanId, ShortDesc FROM PLPlanHeader WHERE ActiveInactive = 'Active' AND PLPlanKey = 65" plan_headers = VhcsRecord.connection.select_all(sql_query) plan_headers.each do |ph| @@ -202,57 +202,57 @@ plan_headers.each do |ph| end end -Vhcs::HlidCardProvider.all.each do |vhcs| - CardProvider.find_or_create_by(provider_code: vhcs.provider_code) do |cp| - cp.provider_line_1 = vhcs.provider_line_1 - cp.provider_line_2 = vhcs.provider_line_2 - cp.provider_line_3 = vhcs.provider_line_3 - cp.provider_line_4 = vhcs.provider_line_4 - cp.provider_line_5 = vhcs.provider_line_5 - cp.provider_line_6 = vhcs.provider_line_6 - cp.provider_line_7 = vhcs.provider_line_7 - cp.provider_line_8 = vhcs.provider_line_8 - cp.provider_line_9 = vhcs.provider_line_9 - cp.provider_line_10 = vhcs.provider_line_10 - cp.provider_line_11 = vhcs.provider_line_11 - cp.provider_line_12 = vhcs.provider_line_12 +# Vhcs::HlidCardProvider.all.each do |vhcs| +# CardProvider.find_or_create_by(provider_code: vhcs.provider_code) do |cp| +# cp.provider_line_1 = vhcs.provider_line_1 +# cp.provider_line_2 = vhcs.provider_line_2 +# cp.provider_line_3 = vhcs.provider_line_3 +# cp.provider_line_4 = vhcs.provider_line_4 +# cp.provider_line_5 = vhcs.provider_line_5 +# cp.provider_line_6 = vhcs.provider_line_6 +# cp.provider_line_7 = vhcs.provider_line_7 +# cp.provider_line_8 = vhcs.provider_line_8 +# cp.provider_line_9 = vhcs.provider_line_9 +# cp.provider_line_10 = vhcs.provider_line_10 +# cp.provider_line_11 = vhcs.provider_line_11 +# cp.provider_line_12 = vhcs.provider_line_12 - cp.claim_to_1 = vhcs.claim_to_1 - cp.claim_to_2 = vhcs.claim_to_2 - cp.claim_to_3 = vhcs.claim_to_3 - cp.claim_to_4 = vhcs.claim_to_4 - cp.claim_to_5 = vhcs.claim_to_5 - cp.claim_to_6 = vhcs.claim_to_6 - cp.claim_to_7 = vhcs.claim_to_7 - cp.claim_to_8 = vhcs.claim_to_8 - cp.claim_to_9 = vhcs.claim_to_9 - cp.claim_to_10 = vhcs.claim_to_10 - cp.claim_to_11 = vhcs.claim_to_11 - cp.claim_to_12 = vhcs.claim_to_12 +# cp.claim_to_1 = vhcs.claim_to_1 +# cp.claim_to_2 = vhcs.claim_to_2 +# cp.claim_to_3 = vhcs.claim_to_3 +# cp.claim_to_4 = vhcs.claim_to_4 +# cp.claim_to_5 = vhcs.claim_to_5 +# cp.claim_to_6 = vhcs.claim_to_6 +# cp.claim_to_7 = vhcs.claim_to_7 +# cp.claim_to_8 = vhcs.claim_to_8 +# cp.claim_to_9 = vhcs.claim_to_9 +# cp.claim_to_10 = vhcs.claim_to_10 +# cp.claim_to_11 = vhcs.claim_to_11 +# cp.claim_to_12 = vhcs.claim_to_12 - cp.mail_to = vhcs.mail_to - cp.mail_to_2 = vhcs.mail_to_2 +# cp.mail_to = vhcs.mail_to +# cp.mail_to_2 = vhcs.mail_to_2 - cp.contact_line_1 = vhcs.contact_line_1 - cp.contact_line_2 = vhcs.contact_line_2 - cp.contact_line_3 = vhcs.contact_line_3 +# cp.contact_line_1 = vhcs.contact_line_1 +# cp.contact_line_2 = vhcs.contact_line_2 +# cp.contact_line_3 = vhcs.contact_line_3 - cp.group_number = vhcs.group_number - cp.rx_group_id = vhcs.rx_group_id - cp.rx_contact = vhcs.rx_contact +# cp.group_number = vhcs.group_number +# cp.rx_group_id = vhcs.rx_group_id +# cp.rx_contact = vhcs.rx_contact - cp.provider_lookup_1 = vhcs.provider_lookup_1 - cp.provider_lookup_2 = vhcs.provider_lookup_2 +# cp.provider_lookup_1 = vhcs.provider_lookup_1 +# cp.provider_lookup_2 = vhcs.provider_lookup_2 - cp.precert_1 = vhcs.precert_1 - cp.precert_2 = vhcs.precert_2 - cp.precert_3 = vhcs.precert_3 - cp.precert_4 = vhcs.precert_4 - cp.precert_5 = vhcs.precert_5 - cp.precert_6 = vhcs.precert_6 +# cp.precert_1 = vhcs.precert_1 +# cp.precert_2 = vhcs.precert_2 +# cp.precert_3 = vhcs.precert_3 +# cp.precert_4 = vhcs.precert_4 +# cp.precert_5 = vhcs.precert_5 +# cp.precert_6 = vhcs.precert_6 - end -end +# end +# end Vhcs::HlrxCrosRef.all.each do |vhcs| rx = CardRx.find_or_create_by(help_desk: vhcs.help_desk, customer_service: vhcs.customer_service, web_url: vhcs.web_url) diff --git a/development3.Dockerfile b/development3.Dockerfile index f338595..0d7468b 100644 --- a/development3.Dockerfile +++ b/development3.Dockerfile @@ -1,6 +1,6 @@ # ----- Build Stage ----- # Using a specific Ruby version (e.g., 3.3) for stability -ARG RUBY_VERSION=3.3.9 +ARG RUBY_VERSION=3.4.8 FROM docker.io/library/ruby:$RUBY_VERSION-slim as base # Install production system dependencies diff --git a/lib/tasks/employer.rake b/lib/tasks/employer.rake new file mode 100644 index 0000000..665d4fc --- /dev/null +++ b/lib/tasks/employer.rake @@ -0,0 +1,83 @@ +namespace :employer do + + desc "TODO" + # rake employer:vhcs_sync_all + task vhcs_sync_all: :environment do + sql_query = "SELECT PLPlanKey, PlanId, ShortDesc FROM PLPlanHeader WHERE ActiveInactive = 'Active' AND PLPlanKey = 65" + plan_headers = VhcsRecord.connection.select_all(sql_query) + + plan_headers.each do |ph| + import_employer = Employer.find_or_create_by!(pl_plan_key: ph['PLPlanKey']) do |em| + puts "Importing #{ph['ShortDesc'].strip}" + em.name = ph['ShortDesc'].strip + em.plan_id = ph['PlanId'].strip.to_i + + + id_card_templates = determine_id_card_templates(em.pl_plan_key) + em.single_card_template = id_card_templates[:single_card_template] + em.multiple_card_template = id_card_templates[:multiple_card_template] + + plan_code = Vhcs::HlPlanCode.find_by(plan_key: em.pl_plan_key) + em.group_number = plan_code.group_number + em.rx_group_number = plan_code.medical_number + em.effective_date = plan_code.effect_date.strftime("%m/%d/%Y") + + pb_company_plan = Vhcs::PbCompanyPlans.find_by(pl_plan_key: em.pl_plan_key) + em.company_pb_entity_key = pb_company_plan.company_pb_entity_key + + card_display_name = Vhcs::PbEntity.find_by(company_pb_entity_key: em.company_pb_entity_key).last_name + em.id_card_display_name = em.employer_trim_name(card_display_name) + + em.default_network_logo = determine_network_logos(em.pl_plan_key) + end + + vhcs_plans = Vhcs::PbProduct.where(company_pb_entity_key: import_employer.company_pb_entity_key) + vhcs_plans.each do |vp| + puts "~~ Importing #{vp.short_description}" + import_plan = import_employer.plans.find_or_create_by!(pb_product_key: vp.pb_product_key) do |pl| + pl.title = vp.short_description + end + vhcs_plan_benefits = Vhcs::HlEgglestonCardBenefit.where(plan_id: import_plan.pb_product_key) + vhcs_plan_benefits.each do |vb| + import_plan.plan_benefits.find_or_create_by!(benefit_desc: vb.benefit_desc) do |pb| + pb.sequence = vb.sequence + pb.benefit = vb.benefit + end + end + end + end + end + + + + desc "TODO" + # rake employer:import_members_from_vhcs[67] + task :import_members_from_vhcs, [:pl_plan_key] => :environment do |t, args| + pl_plan_key = args[:pl_plan_key] + employer = Employer.find_by(pl_plan_key: pl_plan_key) + + vw_mb_members = Vhcs::VwmbMember.where(enrollee_type_value_id: 1, pl_plan_key: pl_plan_key).select(:mb_member_key, :pb_entity_key, :pl_plan_key, :family_id, :full_name_last_name_first) + vw_mb_members_count = vw_mb_members.length + + vw_mb_members.each_with_index do |vwm, i| + Member.find_or_create_by!(mb_member_key: vwm.mb_member_key) do |me| + me.name = vwm.full_name_last_name_first.titleize + me.pb_entity_key = vwm.pb_entity_key + me.family_id = vwm.family_id + me.pl_plan_key = vwm.pl_plan_key + me.employer = employer + + card_display_name = Vhcs::PbEntity.find_by(pb_entity_key: me.pb_entity_key).full_name + me.id_card_display_name = card_display_name + + plan_pb_product_key = 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" = ?', me.pb_entity_key).first.pb_product_key + if plan = Plan.find_by(pb_product_key: plan_pb_product_key) + me.plan = plan + end + end + puts "Employer #{employer.name} (#{i}/#{vw_mb_members_count}) members imported" + end + + end + +end diff --git a/lib/tasks/member.rake b/lib/tasks/member.rake new file mode 100644 index 0000000..a3e2408 --- /dev/null +++ b/lib/tasks/member.rake @@ -0,0 +1,26 @@ +namespace :member do + desc "TODO" + # rake member:import_from_vhcs[123456,1] + task :import_from_vhcs, [:mb_member_key, :employer_id] => :environment do |t, args| + mb_member_key = args[:mb_member_key] + employer_id = args[:employer_id] + + Member.find_or_create_by!(mb_member_key: mb_member_key) do |me| + me.name = vwm.full_name_last_name_first.titleize + me.pb_entity_key = vwm.pb_entity_key + me.family_id = vwm.family_id + me.pl_plan_key = vwm.pl_plan_key + me.employer_id = employer_id + + card_display_name = Vhcs::PbEntity.find_by(pb_entity_key: me.pb_entity_key).full_name + me.id_card_display_name = card_display_name + + plan_pb_product_key = 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" = ?', me.pb_entity_key).first.pb_product_key + if plan = Plan.find_by(pb_product_key: plan_pb_product_key) + me.plan = plan + end + end + + end + +end diff --git a/web.config b/web.config new file mode 100644 index 0000000..17b45af --- /dev/null +++ b/web.config @@ -0,0 +1,19 @@ + + + + + + + + + + + + +