stable, before a refactor

This commit is contained in:
Jason Jordan
2026-03-03 22:53:21 -05:00
parent 4fac3b1036
commit 942d60c3e0
66 changed files with 1321 additions and 194 deletions
+3 -3
View File
@@ -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
+24 -1
View File
@@ -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
+1 -1
View File
@@ -70,7 +70,7 @@ class TailwindFormBuilder < ActionView::Helpers::FormBuilder
text, label_opts = if label_options.present?
[label_options[:text], label_options.except(:text)]
else
[nil, {}]
[object_method.to_s.titleize, {}]
end
label_classes = label_opts[:class] || "block text-platinum font-bold md:text-right mb-1 md:mb-0 pr-4"
@@ -4,19 +4,23 @@ export default class extends Controller {
static values = {
formColor: { type: Array, default: [] } // Declares 'items' as an Array value
}
static targets = ["template", "container", "networkLogo", "button"]
static targets = ["exceptionTemplate", "exceptionContainer", "exception", "exceptionButton"]
add(event) {
connect(){
console.log(this.formColorValue)
}
addExemption(event) {
event.preventDefault()
event.stopPropagation()
const content = this.#updateTemplateNetwork()
const content = this.#newExemption()
this.buttonTarget.insertAdjacentHTML('beforebegin', content);
this.exceptionButtonTarget.insertAdjacentHTML('beforebegin', content);
// this.containerTarget.insertAdjacentHTML("beforeend", content)
}
remove(event) {
removeExemption(event) {
event.preventDefault();
const wrapper = event.target.closest(".network-item");
if (wrapper.dataset.newRecord === "true") {
@@ -30,22 +34,19 @@ export default class extends Controller {
}
}
#updateTemplateNetwork() {
const nextIndex = this.networkLogoTargets.length
#newExemption() {
const nextIndex = this.exceptionTargets.length
const num_of_colors = this.formColorValue.length
let colorIndex = 0
let newSecondaryColor = "copper"
if (nextIndex != 0) {
colorIndex = nextIndex % num_of_colors
if (nextIndex % 2 == 1) {
newSecondaryColor = "bronze"
}
}
const newColor = this.formColorValue[colorIndex]
return this.templateTarget.innerHTML
return this.exceptionTemplateTarget.innerHTML
.replace(/NEW_RECORD/g, nextIndex)
.replace(/NEXT_COLOR/g, newColor)
.replace(/NEXT_SECONDARY_COLOR/g, newSecondaryColor)
}
}
@@ -0,0 +1,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)
}
}
@@ -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");
}
}
}
}
@@ -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) {
+10
View File
@@ -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
+25
View File
@@ -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
+10
View File
@@ -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
+4 -1
View File
@@ -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,
+1 -1
View File
@@ -1,5 +1,5 @@
module Vhcs
class HLEggIdCardDependent < VhcsRecord
class HlEggIdCardDependent < VhcsRecord
self.table_name = 'HLEggIdCardDependent'
+219
View File
@@ -0,0 +1,219 @@
module Vhcs
class HlidCardEggData < VhcsRecord
self.table_name = 'HLIDCardEggData'
alias_attribute :id, :ID
alias_attribute :facility, :Facility
alias_attribute :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
+1 -1
View File
@@ -1,5 +1,5 @@
module Vhcs
class HLIDCardsEgg < VhcsRecord
class HlidCardsEgg < VhcsRecord
self.table_name = 'HLIDCardsEgg'
+14
View File
@@ -0,0 +1,14 @@
class CallStoredProc
def initialize(procedure_name, args = {})
@procedure_name = procedure_name
@args = args
end
def call
params_sql = @args.map { |key, value| "@#{key} = :#{key}" }.join(', ')
sql_template = "EXEC #{@procedure_name} #{params_sql}"
sanitized_sql = VhcsRecord.send(:sanitize_sql_array, [sql_template, @args])
VhcsRecord.connection.exec_query(sanitized_sql)
end
end
@@ -0,0 +1,94 @@
class GetAllIDCardDataByPlanTPAQuery
def initialize(pl_plan_key)
@pl_plan_key = ActiveRecord::Base.connection.quote(pl_plan_key)
end
def call
VhcsRecord.connection.exec_query(sql).rows
end
def to_id_cards_data
raw_data = call
all_id_cards_data = []
raw_data.each do |rd|
id_card_data = {
id: rd[0],
mb_member_key: rd[1],
mbr_type: rd[2],
division: rd[3],
full_name: rd[7],
family_id: rd[8],
mbr_class: rd[9],
effect_date: rd[11],
state: rd[12],
pl_plan_key: rd[14],
group_number: rd[15],
medical_group_num: rd[16],
dental_group_num: rd[17],
pb_product_key: rd[18],
mb_member_key: rd[19]
}
all_id_cards_data.push(id_card_data)
end
all_id_cards_data
end
private
def sql
<<~SQL
SELECT DISTINCT ROW_NUMBER() OVER(ORDER BY pbm.FamilyId ASC) as Id, pbc.MBMemberKey,
CASE WHEN div.PBENtityKey = 344215 OR div.PBENtityKey = 344217 THEN 'OSB' ELSE ou.CompanyNumber END as MbrType,
substring(div.LastName,0,41) as Div ,
substring(pbe.FirstName,0,25) as MbrFirst,
substring(pbe.MiddleName,0,25) as MbrMiddle,
substring(pbe.LastName,0,50) as MbrLast,
(substring(pbe.FirstName, 0, 25) + ' ' + substring(pbe.LastName, 0, 50)) as FullName,
pbm.FamilyId,
UPPER(lct.shortdesc) as MbrClass,
2 as MedOrDent,pp.InEffect as EffectDate,
pbea.State,ISNULL(oua.State,pbea.State) as EmpState,
M.PLPlanKey,
PC.GroupNumber,
PC.MedicalNumber,
PC.DentalNumber,
P.PBProductKey,
m.PBEntityKey as PrimaryMBMemberKey
FROM VWMBMember M INNER JOIN PBEntityClaimsData pbc on pbc.MBMemberKey=M.MBMemberKey
LEFT OUTER Join HLPlanCode PC ON PC.PlanKey = M.PLPlanKey
INNER JOIN PBMember pbm on pbm.PBEntityKey=pbc.PBEntityKey and pbm.EnrolleeTypeKey=1044
INNER JOIN PBEntity pbe on pbe.PBEntityKey=pbm.PBEntityKey
INNER JOIN PBEntityAddress pbea on pbea.PBEntityKey=pbe.PBEntityKey and pbea.AddressTypeID=1137
INNER JOIN PBCoveredEntities ce on ce.PBEntityKey=pbe.PBEntityKey
INNER JOIN PBProductParticipation pp on pp.PBProductParticipationKey=ce.PBProductParticipationKey
INNER JOIN (SELECT ce1.PBEntityKey, pp1.PBProductAvailabilityKey, MAX(pp1.WhenLastChanged) as WhenLastChanged,
pp1.CoverageTypeCode
FROM PBCoveredEntities ce1
INNER JOIN PBProductParticipation pp1 on pp1.PBProductParticipationKey = ce1.PBProductParticipationKey
GROUP BY ce1.PBEntityKey, pp1.PBProductAvailabilityKey,pp1.CoverageTypeCode)
cepp ON cepp.PBEntityKey = ce.PBEntityKey AND cepp.PBProductAvailabilityKey = pp.PBProductAvailabilityKey
and cepp.CoverageTypeCode = pp.CoverageTypeCode
INNER JOIN GEN_LookupTables lct ON lct.RecordID = pp.CoverageTypeCode
INNER JOIN PBProductAvailability pa on pa.PBProductAvailabilityKey=pp.PBProductAvailabilityKey
INNER JOIN PBProduct p on p.PBProductKey=pa.PBProductKey
INNER JOIN PBAffiliation aff ON aff.PBAffiliationKey = pp.PBAffiliationKey
INNER JOIN PBEntity div on div.PBEntityKey=aff.ParentPBEntityKey
LEFT OUTER JOIN PBOrgUnit ou on ou.PBEntityKey=div.PBEntityKey
LEFT OUTER JOIN PBEntityAddress oua on oua.PBEntityKey=ou.PBEntityKey and oua.AddressTypeID=1137 WHERE p.PBProductKey in (Select DISTINCT PBProductKey From PBProduct Where FullDescription NOT LIKE '%LIFE%' AND FullDescription NOT LIKE '%VIS%')
AND pp.InEffect <= getdate() +90
AND (pp.OutOfEffect-1 > getdate() AND
pp.OutOfEffect>pp.InEffect)
AND pp.OutOfEffect=(Select Max(Part.OutOfEffect) From PBProductParticipation Part
INNER JOIN PBProductAvailability Aval on Aval.PBProductAvailabilityKey=Part.PBProductAvailabilityKey
INNER JOIN PBProduct Prod on Prod.PBProductKey=Aval.PBProductKey
Where Prod.PBProductKey = p.PBProductKey
AND Part.PBProductParticipationKey = pp.PBProductParticipationKey)
AND M.EnrolleeTypeKey = '1044'
AND M.PLPlanKey = #{@pl_plan_key}
SQL
end
end
+95
View File
@@ -0,0 +1,95 @@
class GetIdCardDataTpaQuery
def initialize(family_id)
@family_id = ActiveRecord::Base.connection.quote(family_id)
if family_id.length == 9
@entity_type = ActiveRecord::Base.connection.quote("FamilyId")
else
@entity_type = ActiveRecord::Base.connection.quote("PBEntityKey")
end
end
def call
VhcsRecord.connection.exec_query(sql).rows.first
end
def to_id_card_data
raw_data = call
id_card_data = {
id: raw_data[0],
mb_member_key: raw_data[1],
mbr_type: raw_data[2],
division: raw_data[3],
full_name: raw_data[7],
family_id: raw_data[8],
mbr_class: raw_data[9],
effect_date: raw_data[11],
state: raw_data[12],
pl_plan_key: raw_data[14],
group_number: raw_data[15],
medical_group_num: raw_data[16],
dental_group_num: raw_data[17],
pb_product_key: raw_data[18],
mb_member_key: raw_data[19]
}
[id_card_data]
end
private
def sql
<<~SQL
SELECT DISTINCT ROW_NUMBER() OVER(ORDER BY pbm.FamilyId ASC) as Id, pbc.MBMemberKey,
isnull(ou.CompanyNumber,'') as MbrType,
CASE WHEN m.PLPlanKey = '14' THEN 'DUPLIN COUNTY GOVERNMENT' ELSE substring(div.LastName,0,41) END as Div,
substring(pbe.FirstName,0,25) as MbrFirst,
substring(pbe.MiddleName,0,25) as MbrMiddle,
substring(pbe.LastName,0,50) as MbrLast,
(substring(pbe.FirstName, 0, 25) + ' ' + substring(pbe.LastName, 0, 50)) as FullName,
pbm.FamilyId,
UPPER(lct.shortdesc) as MbrClass,
2 as MedOrDent,
pp.InEffect as EffectDate,
pbea.State,ISNULL(oua.State,pbea.State) as EmpState,
M.PLPlanKey,
PC.GroupNumber,
PC.MedicalNumber,
PC.DentalNumber,
P.PBProductKey,
m.PBEntityKey as PrimaryMBMemberKey
FROM VWMBMember M
INNER JOIN PBEntityClaimsData pbc on pbc.MBMemberKey=M.MBMemberKey
Inner Join HLPlanCode PC ON PC.PlanKey = M.PLPlanKey
INNER JOIN PBMember pbm on pbm.PBEntityKey=pbc.PBEntityKey and pbm.EnrolleeTypeKey=1044
INNER JOIN PBEntity pbe on pbe.PBEntityKey=pbm.PBEntityKey
INNER JOIN PBEntityAddress pbea on pbea.PBEntityKey=pbe.PBEntityKey and pbea.AddressTypeID=1137
INNER JOIN PBCoveredEntities ce on ce.PBEntityKey=pbe.PBEntityKey
INNER JOIN PBProductParticipation pp on pp.PBProductParticipationKey=ce.PBProductParticipationKey
INNER JOIN (SELECT ce1.PBEntityKey, pp1.PBProductAvailabilityKey, MAX(pp1.WhenLastChanged) as WhenLastChanged,
pp1.CoverageTypeCode
FROM PBCoveredEntities ce1
INNER JOIN PBProductParticipation pp1 on pp1.PBProductParticipationKey = ce1.PBProductParticipationKey
GROUP BY ce1.PBEntityKey, pp1.PBProductAvailabilityKey,pp1.CoverageTypeCode)
cepp ON cepp.PBEntityKey = ce.PBEntityKey AND cepp.PBProductAvailabilityKey = pp.PBProductAvailabilityKey
and cepp.CoverageTypeCode = pp.CoverageTypeCode
INNER JOIN GEN_LookupTables lct ON lct.RecordID = pp.CoverageTypeCode
INNER JOIN PBProductAvailability pa on pa.PBProductAvailabilityKey=pp.PBProductAvailabilityKey
INNER JOIN PBProduct p on p.PBProductKey=pa.PBProductKey
INNER JOIN PBAffiliation aff ON aff.PBAffiliationKey = pp.PBAffiliationKey
INNER JOIN PBEntity div on div.PBEntityKey=aff.ParentPBEntityKey
LEFT OUTER JOIN PBOrgUnit ou on ou.PBEntityKey=div.PBEntityKey
LEFT OUTER JOIN PBEntityAddress oua on oua.PBEntityKey=ou.PBEntityKey and oua.AddressTypeID=1137
WHERE p.PBProductKey in (Select PBProductKey From PBProduct Where FullDescription NOT LIKE '%LIFE%' AND FullDescription NOT LIKE '%VISION%' AND FullDescription NOT LIKE '%DENT%')
AND pp.InEffect <= getdate() +90
AND (pp.OutOfEffect-1 > getdate() AND pp.OutOfEffect>pp.InEffect)
AND pp.OutOfEffect=(Select Max(Part.OutOfEffect) From PBProductParticipation Part
INNER JOIN PBProductAvailability Aval on Aval.PBProductAvailabilityKey=Part.PBProductAvailabilityKey
INNER JOIN PBProduct Prod on Prod.PBProductKey=Aval.PBProductKey
Where Prod.PBProductKey = p.PBProductKey
AND Part.PBProductParticipationKey = pp.PBProductParticipationKey)
AND pbm.#{@entity_type}=#{@family_id}
AND M.EnrolleeTypeKey='1044'
SQL
end
end
View File
+47 -8
View File
@@ -6,7 +6,7 @@ module EmployerCards
end
def call
@members = @employer.members
@members = @employer.members.order(:name)
@employer_cards = []
init_cards_and_set_member_fields
@@ -19,6 +19,31 @@ module EmployerCards
private
def init_cards_and_set_common_fields
employer_attributes = {
employer_name: @employer.id_card_display_name,
group_number: @employer.group_number,
rx_group: @employer.rx_group_number
}
rx_attributes = @employer.card_rx.attributes.with_indifferent_access.slice(
:customer_service,
:web_url
)
provider_attributes = @employer.card_provider.attributes.with_indifferent_access.slice(
:provider_code, :provider_line_1, :provider_line_2, :provider_line_3, :provider_line_4, :provider_line_5, :provider_line_6,
:provider_line_7, :provider_line_8, :provider_line_9, :provider_line_10, :provider_line_11, :provider_line_12,
:claim_to_1, :claim_to_2, :claim_to_3, :claim_to_4, :claim_to_5, :claim_to_6,
:claim_to_7, :claim_to_8, :claim_to_9, :claim_to_10, :claim_to_11, :claim_to_12
)
selected_attributes = employer_attributes.merge(rx_attributes).merge(provider_attributes)
@employer_cards.each do |card|
card.assign_attributes(selected_attributes)
end
end
def set_common_fields
employer_attributes = {
employer_name: @employer.id_card_display_name,
@@ -32,7 +57,7 @@ module EmployerCards
)
provider_attributes = @employer.card_provider.attributes.with_indifferent_access.slice(
:provider_line_1, :provider_line_2, :provider_line_3, :provider_line_4, :provider_line_5, :provider_line_6,
:provider_code, :provider_line_1, :provider_line_2, :provider_line_3, :provider_line_4, :provider_line_5, :provider_line_6,
:provider_line_7, :provider_line_8, :provider_line_9, :provider_line_10, :provider_line_11, :provider_line_12,
:claim_to_1, :claim_to_2, :claim_to_3, :claim_to_4, :claim_to_5, :claim_to_6,
:claim_to_7, :claim_to_8, :claim_to_9, :claim_to_10, :claim_to_11, :claim_to_12
@@ -58,21 +83,29 @@ module EmployerCards
end
def init_cards_and_set_member_fields
@group_dependents = Vhcs::VwmbMember.where(pl_plan_key: @employer.pl_plan_key)
@members.each do |me|
effect_date = determine_eff_date(me)
if effect_date
member_card = SampleIdCard.new()
selected_attributes = {
member_attributes = {
full_name: me.id_card_display_name,
primary_mb_member_key: me.mb_member_key,
name: me.name,
primary_mb_member_key: me.pb_entity_key,
family_id: me.family_id,
plan_id: me.plan_id,
medical_eff_date: effect_date.strftime("%m/%d/%Y")
}
dependent_attributes = get_dependent_fields(me)
selected_attributes = member_attributes.merge(dependent_attributes)
member_card.assign_attributes(selected_attributes)
@employer_cards.push(member_card)
if dependent_attributes.present?
@employer_cards.push(member_card)
end
end
end
end
@@ -102,7 +135,7 @@ module EmployerCards
def determine_eff_date(member)
participation = Vhcs::PbProductParticipation.joins('INNER JOIN "PBCoveredEntities" ON "PBProductParticipation"."PBProductParticipationKey" = "PBCoveredEntities"."PBProductParticipationKey"').where('"PBCoveredEntities"."PBEntityKey" = ?', member.pb_entity_key).first
participation = Vhcs::PbProductParticipation.joins('INNER JOIN "PBCoveredEntities" ON "PBProductParticipation"."PBProductParticipationKey" = "PBCoveredEntities"."PBProductParticipationKey"').where('"PBCoveredEntities"."PBEntityKey" = ?', member.pb_entity_key).last
in_effect = participation.in_effect
out_of_effect = participation.out_of_effect
@@ -114,8 +147,14 @@ module EmployerCards
end
def set_dependent_fields
# Not needed for sample card
def get_dependent_fields(member)
dependent_attributes = {}
dependents = @group_dependents.where(family_id: member.family_id).where.not(pb_entity_key: member.pb_entity_key)
dependents.each do |dep|
dependent_name = dep.first_name + ' ' + dep.last_name
dependent_attributes["dependent_#{dep.sequence_number - 1}".to_sym] = dependent_name
end
dependent_attributes
end
end
end
@@ -1,17 +1,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
+34 -9
View File
@@ -1,22 +1,47 @@
class EmployerCardsGenerator
def initialize(employer)
def initialize(employer, layout)
@employer = employer
@layout = layout
end
def call
SampleIdCard.where(employer_name: @employer.id_card_display_name).destroy_all
EmployerCards::DataFormatter.new(@employer).call
group_cards_pdf = CombinePDF.new
SampleIdCard.where(employer_name: @employer.id_card_display_name).each do |card|
urls = EmployerCards::JasperUrlGenerator.new(@employer, card.family_id).call
puts urls
card_front_pdf = SampleCard::JasperPdfGenerator.new(urls.first).call
card_back_pdf = SampleCard::JasperPdfGenerator.new(urls.last).call
if @layout == "FullPageCard"
group_cards_pdf_array = []
reprint = Vhcs::HlidCardEggData.where(group_number: @employer.group_number).pluck(:family_id)
SampleIdCard.where(employer_name: @employer.id_card_display_name).each do |card|
if reprint.include?(card.family_id)
url = EmployerCards::JasperUrlGenerator.new(@employer, card.family_id, @layout).call
puts url
card_pdf = SampleCard::JasperPdfGenerator.new(url).call
card_filename = "#{card.name.gsub(", ","_")}_digital_card_#{Date.today}.pdf"
# group_cards_pdf_array.add(card_filename, pdf_object.to_pdf)
group_cards_pdf_array << { name: card_filename, data: card_pdf.to_pdf }
end
end
group_cards_pdf << card_front_pdf
group_cards_pdf << card_back_pdf
# Initialize a string-based IO object
group_cards_pdf = Zip::OutputStream.write_buffer do |zio|
group_cards_pdf_array.each do |file|
zio.put_next_entry(file[:name])
zio.write(file[:data])
end
end
else
group_cards_pdf = CombinePDF.new
reprint = Vhcs::HlidCardEggData.where(group_number: @employer.group_number).pluck(:family_id)
SampleIdCard.where(employer_name: @employer.id_card_display_name).each do |card|
if reprint.include?(card.family_id)
url = EmployerCards::JasperUrlGenerator.new(@employer, card.family_id, @layout).call
puts url
card_pdf = SampleCard::JasperPdfGenerator.new(url).call
group_cards_pdf << card_pdf
end
end
end
# todays_date = DateTime.current.strftime('%Y%m%d%H%M%S')
+14 -2
View File
@@ -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
@@ -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
+1 -1
View File
@@ -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
+1 -1
View File
@@ -10,7 +10,7 @@
<div class="flex flex-col space-y-6 w-3/5">
<div class="flex space-x-10">
<div class="w-full">
<%= 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" %>
</div>
<div class="w-full">
<%= f.text_field :slug, label: { text: "Slug" }, class: "w-full" %>
@@ -0,0 +1,15 @@
<div class="flex items-end w-[42%] hidden exception-item" data-controller="logo-upload">
<div class="flex flex-col w-full">
<%= exception_item_fields.select :card_logo_file_id, options_for_select(CardLogoFile.where(logo_type: 'network').pluck(:filename)), { include_blank: "Select/Add Network Logo", class: "rounded-r-none flex flex-col" }, { data: { logo_upload_target: "logofield", general_form_target: "dependentField", parent_value: "network_logo", add_exception_target: "exception" }} %>
</div>
<div class="flex items-center justify-center cursor-pointer bg-NEXT_COLOR hover:bg-deepcove border-2 border-NEXT_COLOR text-platinum font-bold px-3 rounded-r h-10 transition duration-100">
<label for="file_upload_input_NEW_ITEM_RECORD" class="text-center cursor-pointer">
<%= icon "image-plus", library: "lucide" %>
</label>
</div>
<div class="hidden flex justify-center ml-4 rounded-lg border-4 border-NEXT_COLOR" data-logo-upload-target="previewContainer">
<img data-logo-upload-target="preview" src="#" alt="Network Logo preview" class="max-h-[100px] max-w-[133px] m-1 bg-platinum"/>
</div>
<%= exception_item_fields.file_field :logo_file, class: "hidden", id: "file_upload_input_NEW_ITEM_RECORD", data: { add_alt_network_logo_target: "networkLogo", logo_upload_type_param: "network", action: "change->logo-upload#uploadLogo" }, direct_upload: true %>
</div>
+2 -1
View File
@@ -118,8 +118,9 @@
<% end %>
</template>
</div>
<div class="py-8">
<div class="flex py-8 space-x-4">
<%= 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" %>
</div>
</div>
<% end %>
+28 -16
View File
@@ -1,21 +1,33 @@
<div class="bg-deepcove h-full w-full flex flex-col justify-start">
<h1 class="font-bold text-4xl text-platinum my-5">Employers</h1>
<% plan_colors = EmployerSetupPlansForm::PLAN_COLORS.push('copper', 'bronze').shuffle %>
<h2 class="font-bold text-3xl text-platinum my-5">In Process:</h2>
<% @employers.inactive.each_with_index do |es, index| %>
<% item_color_index = index == 0 ? 0 : index % plan_colors.length %>
<div class="w-1/2 flex text-2xl text-platinum font-bold px-4 py-4 ml-10 rounded-lg border-l-5 border-b-2 <%= "border-#{plan_colors[item_color_index]}" %>">
<%= link_to es.name, employer_path(es.slug), class: "hover:text-atmosphere" %>
</div>
<% end %>
<div class="w-1/2 flex text-2xl text-limegreen font-bold px-4 py-4 ml-10 rounded-lg border-l-5 border-b-2 border-platinum">
<%= link_to "New Employer", new_employer_path, class: "hover:text-verdigris" %>
<div class="flex items-center">
<h1 class="font-bold text-4xl text-platinum my-5">Employers</h1>
<%= 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 %>
</div>
<h2 class="font-bold text-3xl text-platinum my-5">Live:</h2>
<% @employers.active.each_with_index do |es, index| %>
<% item_color_index = index == 0 ? 0 : index % plan_colors.length %>
<div class="w-1/2 flex text-2xl text-platinum font-bold px-4 py-4 ml-10 rounded-lg border-l-5 border-b-2 <%= "border-#{plan_colors[item_color_index]}" %>">
<%= link_to es.name, employer_path(es.slug), class: "hover:text-atmosphere" %>
<% plan_colors = EmployerSetupPlansForm::PLAN_COLORS.push('copper', 'bronze').shuffle %>
<% @color_index = 0 %>
<h2 class="font-bold text-3xl text-brightlava my-5">In Process:</h2>
<% @employers.inactive.each_with_index do |emp, index| %>
<% item_color_index = @color_index == 0 ? 0 : @color_index % plan_colors.length %>
<div class="w-1/2 flex text-2xl text-platinum font-bold px-4 py-4 ml-10 space-x-4 rounded-lg border-l-5 border-b-2 <%= "border-#{plan_colors[item_color_index]}" %>">
<%= link_to emp.name, employer_path(emp.slug), class: "hover:text-#{plan_colors[item_color_index]}" %>
<div>
<%= "(Effective #{emp.effective_date})" %>
</div>
</div>
<% @color_index += 1 %>
<% end %>
<h2 class="font-bold text-3xl text-limegreen my-5">Live:</h2>
<% @employers.active.each_with_index do |emp, index| %>
<% item_color_index = @color_index == 0 ? 0 : @color_index % plan_colors.length %>
<div class="w-1/2 flex text-2xl text-platinum font-bold px-4 py-4 ml-10 space-x-4 rounded-lg border-l-5 border-b-2 <%= "border-#{plan_colors[item_color_index]}" %>">
<%= link_to emp.name, employer_path(emp.slug), class: "hover:text-#{plan_colors[item_color_index]}" %>
<div>
<%= "(#{emp.members.count} Members)" %>
</div>
</div>
<% @color_index += 1 %>
<% end %>
</div>
+170
View File
@@ -0,0 +1,170 @@
<div class="bg-deepcove h-full w-full flex flex-col">
<div class="flex justify-between">
<h1 class="font-bold text-4xl text-platinum my-5">New Employer</h1>
<%= form_with model: @employer, url: import_employers_path, data: { turbo: false }, local: true, multipart: true do |form| %>
<div class="flex items-end space-x-4">
<div class="flex flex-col">
<%= 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 %>
</div>
<%= form.submit "Import", class: "h-[40px]" %>
</div>
<% end %>
</div>
<%= form_with model: @employer, local: true, multipart: true do |f| %>
<div class="flex flex-col space-y-6 pb-10">
<div class="w-full flex items-center">
<h3 class="font-bold text-2xl text-bluemana">General Information</h3>
<div class="h-[1px] w-1/2 mt-2 bg-bluemana"></div>
</div>
<div class="flex w-full items-end" data-controller="logo-upload">
<div class="flex flex-col space-y-6 w-2/5">
<div class="flex space-x-10">
<div class="w-full">
<%= f.text_field :name, label: { text: "Employer Name" }, data: { logo_upload_target: "employer" }, class: "w-full" %>
</div>
<div class="w-full">
<%= f.text_field :group_number, label: { text: "Group/Medical Number" }, class: "w-full" %>
</div>
</div>
<div class="flex space-x-10">
<div class="w-full">
<%= f.text_field :effective_date, label: { text: "Effective Date" }, class: "w-full" %>
</div>
<div 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 %>
</div>
</div>
<div class="flex items-end">
<div class="flex">
<div class="flex flex-col">
<%= 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 %>
</div>
<div class="flex items-center justify-center self-end cursor-pointer bg-atmosphere hover:bg-deepcove border-2 border-atmosphere text-platinum font-bold px-3 rounded-r h-10 transition duration-100">
<label for="file_upload_input_employer" class="text-center cursor-pointer">
<%= icon "image-plus", library: "lucide" %>
</label>
</div>
</div>
<div class="hidden flex justify-center ml-15 rounded-lg border-4 border-atmosphere" data-logo-upload-target="previewContainer">
<img data-logo-upload-target="preview" src="#" alt="Employer Logo preview" class="max-h-[100px] max-w-[133px] bg-platinum m-1"/>
</div>
<%= 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 %>
</div>
</div>
</div>
<div class="w-full flex items-center">
<h3 class="font-bold text-2xl text-bluemana">Plans Information</h3>
<div class="h-[1px] w-1/2 mt-2 bg-bluemana"></div>
</div>
<div class="w-full flex my-8" data-controller="add-plan" data-add-plan-form-color-value="<%= EmployerSetupPlansForm::PLAN_COLORS.to_json %>" >
<div class="flex flex-wrap w-full" data-add-plan-target="container">
<% @employer.plans.each_with_index do |plan, index| %>
<%= f.fields_for :plans, plan, child_index: index do |plan_fields| %>
<div class="inline-flex flex-col justify-end pr-6 w-1/4 relative pl-1 plan-item" data-controller="benefits-template-picker">
<div class="absolute left-0 top-[2%] h-[98%] border-l-4 <%= "border-#{EmployerSetupPlansForm::PLAN_COLORS[index]}" %> "></div>
<div class="font-bold text-2xl <%= "text-#{EmployerSetupPlansForm::PLAN_COLORS[index]}" %> -ml-[6px] z-2 w-full">
<%= "Plan #{index + 1}" %>
</div>
<%= render 'plan_fields', plan_fields: plan_fields, f: f, index: index %>
<div class="text-xl text-left font-bold pl-[2px] mb-[-4px] z-1 <%= "text-#{EmployerSetupPlansForm::PLAN_COLORS[index]}" %>">
Benefit Values
</div>
<div class="w-full h-[3px] rounded-r <%= "bg-#{index % 2 == 1 ? 'bronze' : 'copper'}" %> ml-[3px]"></div>
<%= plan_fields.fields_for :plan_benefits do |plan_benefits_fields| %>
<%= render 'plan_benefits_fields', plan_benefits_fields: plan_benefits_fields %>
<% end %>
<div class="mt-4 pl-1">
<%= 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" } %>
</div>
</div>
<% 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" } %>
</div>
<template data-add-plan-target="template">
<%= f.fields_for :plans, @employer.build_plan_with_default_benefits, child_index: 'NEW_RECORD' do |plan_fields| %>
<div class="inline-flex flex-col justify-end pr-6 w-1/4 relative pl-1 plan-item" data-controller="benefits-template-picker">
<div class="absolute left-0 top-[2%] h-[98%] border-l-4 border-NEXT_COLOR"></div>
<div class="font-bold text-2xl text-NEXT_COLOR -ml-[6px] z-2 w-full">
<%= "Plan NEW_PLAN" %>
</div>
<%= render 'plan_fields', plan_fields: plan_fields, f: f, index: "NEW_RECORD".to_i %>
<div class="text-xl text-left font-bold pl-[2px] mb-[-4px] z-1 text-NEXT_COLOR">
Benefit Values
</div>
<div class="w-full h-[3px] rounded-r bg-NEXT_SECONDARY_COLOR ml-[3px]"></div>
<%= plan_fields.fields_for :plan_benefits do |plan_benefits_fields| %>
<%= render 'plan_benefits_fields', plan_benefits_fields: plan_benefits_fields %>
<% end %>
<div class="mt-4 pl-1">
<%= plan_fields.hidden_field :_destroy %>
<%= button_tag "Remove Plan NEW_PLAN", class: "cursor-pointer bg-deepcove hover:bg-brightlava text-xl font-bold text-NEXT_SECONDARY_COLOR hover:text-platinum py-2 px-4 font-semibold leading-tight rounded-lg border-3 border-NEXT_SECONDARY_COLOR w-full", data: { action: "add-plan#remove" } %>
</div>
</div>
<% end %>
</template>
</div>
</div>
<div class="w-full flex items-center">
<h3 class="font-bold text-2xl text-bluemana">ID Card Exceptions Information</h3>
<div class="h-[1px] w-1/2 mt-2 bg-bluemana"></div>
</div>
<div class="flex flex-wrap w-full justify-start my-8" data-controller="add-exception" data-add-exception-form-color-value="<%= EmployerSetupPlansForm::PLAN_COLORS.to_json %>">
<%= 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" } %>
<template data-add-exception-target="exceptionTemplate">
<%= f.fields_for :card_exceptions, CardException.new, child_index: 'NEW_RECORD' do |exception_fields| %>
<div class="flex flex-col pr-6 w-1/2 pl-1">
<div class="flex justify-between items-end w-full pb-2">
<div class="w-[48%]">
<%= exception_fields.select :type, options_for_select(CardException::VALID_TYPES.map { |type| [type.titleize(keep_id_suffix: true), type] }), { label: { text: "Exception Based On" }, prompt: "Select Type", class: "w-full" } %>
</div>
<div class="w-[48%]">
<%= exception_fields.text_field :value, label: { text: "Exception Value" }, class: "w-full" %>
</div>
</div>
<div class="text-xl text-left font-bold mb-[-4px] z-1 text-platinum">
Exception Items
</div>
<div class="w-full h-[3px] rounded-r bg-NEXT_COLOR ml-[1px] mb-1"></div>
<div class="flex flex-col w-full justify-start" data-controller="add-exception-item">
<%= button_tag "Add Another Item To Exception", class: "cursor-pointer bg-NEXT_COLOR hover:bg-deepcove text-xl font-bold text-platinum my-3 py-1 font-semibold leading-tight rounded border-3 border-NEXT_COLOR w-full", data: { action: "add-exception-item#addExemptionItem", add_exception_item_target: "exceptionItemButton" } %>
<template data-add-exception-item-target="exceptionItemTemplate">
<%= exception_fields.fields_for :card_exception_items, CardExceptionItem.new, child_index: 'NEW_ITEM_RECORD' do |exception_item_fields| %>
<div class="flex justify-between items-end w-full" data-controller="general-form">
<div class="w-[42%]">
<%= exception_item_fields.select :field_name, options_for_select(CardExceptionItem::VALID_FIELD_NAMES.map { |field_name| [field_name.titleize, field_name] }), { label: { text: "Card Field" }, prompt: "Select Card Field", class: "w-full" }, { data: { action: "change->general-form#toggleFields"} } %>
</div>
<div class="w-[42%] hidden">
<%= exception_item_fields.text_field :field_value, label: { text: "New Value" }, data: { general_form_target: "dependentField", parent_value: "default" }, class: "w-full" %>
</div>
<%= render 'alt_network_logo_fields_new', exception_item_fields: exception_item_fields %>
<div class="w-[42%] hidden">
<%= exception_item_fields.select :card_provider_id, options_for_select(CardProvider.where.not(title: nil).map { |provider| [provider.title, provider.id] }), { prompt: "Select Provider Template", class: "w-full" }, { data: { general_form_target: "dependentField", parent_value: "provider_section" } } %>
</div>
<div class="mt-4 ml-1">
<%= exception_item_fields.hidden_field :_destroy %>
<%= button_tag "Remove", class: "cursor-pointer flex items-center justify-center bg-brightlava font-bold text-lg text-platinum py-2 px-1 font-semibold leading-tight rounded-lg border-3 border-brightlava w-full", data: { action: "add-exception-item#removeExemptionItem" } %>
</div>
</div>
<% end %>
</template>
</div>
</div>
<% end %>
</template>
</div>
<div class="py-8">
<%= f.submit "Submit" %>
</div>
</div>
<% end %>
</div>
+9 -5
View File
@@ -25,17 +25,21 @@
</div>
<% @employer.attributes.with_indifferent_access.slice(:pl_plan_key, :company_pb_entity_key, :group_number).each do |attribute_name, attribute_value| %>
<p class="ml-9 text-<%="#{attribute_value.present? ? "limegreen" : "brightlava"}" %>">
<strong class="text-platinum mr-2">├── <%= attribute_name.humanize %>:</strong>
<strong class="text-platinum mr-2">├── <%= attribute_name.titleize %>:</strong>
<%= attribute_value.present? ? attribute_value.to_s : "waiting" %>
</p>
<% end %>
<div>
<strong class="text-atmosphere mr-2">└── Plans</strong>
</div>
<% @employer.plans.pluck(:title).each do |plan_title| %>
<% @employer.plans.pluck(:title, :pb_product_key).each do |plan| %>
<div class="ml-9">
├── <%= plan_title %>
├── <%= plan.first %>
</div>
<p class="ml-14 text-<%="#{plan.last.present? ? "limegreen" : "brightlava"}" %>">
<strong class="text-platinum mr-2">└── PB Product Key:</strong>
<%= plan.last.present? ? plan.last.to_s : "waiting" %>
</p>
<% end %>
</div>
<div class="w-full flex items-center space-x-2 mt-10 ml-14">
@@ -51,8 +55,8 @@
</div>
<%= 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" %>
</div>
</div>
</div>
+6 -6
View File
@@ -1,9 +1,9 @@
<div class="text-deepcove bg-deepcove border border-deepcove">co</div>
<div class="text-bluetang bg-bluetang border border-bluetang">co</div>
<div class="text-bluetang-tinted bg-bluetang-tinted border border-bluetang-tinted">co</div>
<div class="text-atmosphere bg-atmosphere border border-atmosphere">co</div>
<div class="text-atmosphere-tinted bg-atmosphere-tinted border border-atmosphere-tinted">co</div>
<div class="text-bluemana bg-bluemana border border-bluemana">co</div>
<div class="text-deepcove hover:text-verdigris bg-deepcove border border-deepcove">co</div>
<div class="text-bluetang hover:text-bronze bg-bluetang border border-bluetang">co</div>
<div class="text-bluetang-tinted hover:text-copper bg-bluetang-tinted border border-bluetang-tinted">co</div>
<div class="text-atmosphere hover:text-cobalt bg-atmosphere border border-atmosphere">co</div>
<div class="text-atmosphere-tinted hover:text-atmosphere bg-atmosphere-tinted border border-atmosphere-tinted">co</div>
<div class="text-bluemana hover:text-bluemana bg-bluemana border border-bluemana">co</div>
<div class="text-bluemana-tinted bg-bluemana-tinted border border-bluemana-tinted">co</div>
<div class="text-cobalt bg-cobalt border border-cobalt">co</div>
<div class="text-cobalt-tinted bg-cobalt-tinted border border-cobalt-tinted">co</div>