diff --git a/app/assets/javascripts/assister_role.js b/app/assets/javascripts/assister_role.js index dd8b67e4e99..3cb711c79c7 100644 --- a/app/assets/javascripts/assister_role.js +++ b/app/assets/javascripts/assister_role.js @@ -30,28 +30,8 @@ function selectAssisterAgency(element) { document.getElementById('assister-staff-btn').disabled = false; } -$(document).on('click', 'a.select-assister-agency', function () { +$(document).on('click', 'select-assister-agency', function () { if ($('.table-responsive').length) { $('.assister-agency-submit').removeClass('hidden'); } }); - -function allowAssisterAgencyFormSubmission() { - var assister_attestation_fields = document.getElementsByClassName('assister-attestation-field'); - var form_button = document.getElementById('assister-btn'); - if ( - Array.from(assister_attestation_fields).every( - (form_element) => form_element.checked == true - ) == true - ) { - form_button.disabled = false; - } else { - form_button.disabled = true; - } -} - -$(function () { - $('.assister-attestation-field').on('change', function () { - allowAssisterAgencyFormSubmission(); - }); -}); \ No newline at end of file diff --git a/app/assets/javascripts/help_me_sign_up.js b/app/assets/javascripts/help_me_sign_up.js index 654b6b64577..1ba2ec08715 100644 --- a/app/assets/javascripts/help_me_sign_up.js +++ b/app/assets/javascripts/help_me_sign_up.js @@ -1,71 +1,154 @@ -$(document).on('click', '#search_for_plan_shopping_help', function() { - $.ajax({ - type: 'GET', - data: {firstname: $('#help_first_name').val(), lastname: $('#help_last_name').val(), type: $('#help_type').html(), - person: $('#help_requestor').html(), email: $('#help_requestor_email').html(), - first_name: $('#person_first_name').val(), last_name: $('#person_last_name').val(), - ssn: $('#person_ssn').val(), dob: $('#jq_datepicker_ignore_person_dob').val() - }, - url: '/exchanges/hbx_profiles/request_help.html?', - }).done(function(response) { - $('#help_status').html(JSON.parse(response)['status']) +(function ($) { + var REQUEST_HELP = '/exchanges/hbx_profiles/request_help.html?'; + + /** Shared GET fields for request_help (vanilla DOM reads match prior jQuery .val() / .html()). */ + function personPayload() { + function val(id) { + var el = document.getElementById(id); + return el ? el.value : ''; + } + function html(id) { + var el = document.getElementById(id); + return el ? el.innerHTML : ''; + } + return { + person: html('help_requestor'), + email: html('help_requestor_email'), + first_name: val('person_first_name'), + last_name: val('person_last_name'), + ssn: val('person_ssn'), + dob: val('jq_datepicker_ignore_person_dob') + }; + } + + function personPayloadSearchParams(extraPairs) { + var p = new URLSearchParams(); + if (extraPairs) { + for (var i = 0; i < extraPairs.length; i++) { + p.set(extraPairs[i][0], extraPairs[i][1]); + } + } + var fields = personPayload(); + Object.keys(fields).forEach(function (key) { + p.set(key, fields[key]); + }); + return p; + } + + $(document).on('click', '#search_for_plan_shopping_help', function () { + $.ajax({ + type: 'GET', + data: $.extend( + { + firstname: $('#help_first_name').val(), + lastname: $('#help_last_name').val(), + type: $('#help_type').html() + }, + personPayload() + ), + url: REQUEST_HELP + }).done(function (response) { + $('#help_status').html(JSON.parse(response).status); + }); + }); + + $(document).on('click', '.help_button', function () { + $.ajax({ + type: 'GET', + data: $.extend( + { + assister: this.getAttribute('data-assister'), + broker: this.getAttribute('data-broker') + }, + personPayload() + ), + url: REQUEST_HELP + }).done(function (response) { + var parsed = JSON.parse(response); + $('#help_index_status').html(parsed.status).removeClass('hide'); + $('#consumer_brokers_widget').html(parsed.broker); + }); + }); + + $(document).on('click', '.name_search_only', function () { + $('#help_list').addClass('hide'); + $('#help_search').removeClass('hide'); + $('#help_type').html(this.id); + $('#back_to_help').removeClass('hide'); }); -}) -$(document).on('click', '.help_button', function(){ -$.ajax({ - type: 'GET', - data: {assister: this.getAttribute('data-assister'), broker: this.getAttribute('data-broker'), - person: $('#help_requestor').html(), email: $('#help_requestor_email').html(), - first_name: $('#person_first_name').val(), last_name: $('#person_last_name').val(), - ssn: $('#person_ssn').val(), dob: $('#jq_datepicker_ignore_person_dob').val() - }, - url: '/exchanges/hbx_profiles/request_help.html?', - }).done(function(response) { - broker_status = JSON.parse(response) - var status = broker_status['status'] - var broker = broker_status['broker'] - $('#help_index_status').html(status).removeClass('hide') - $('#consumer_brokers_widget').html(broker) + $(document).on('click', '[data-target="#help_with_plan_shopping"]', function () { + $('.help_reset').addClass('hide'); + $('#help_list').removeClass('hide'); + $('#back_to_help').addClass('hide'); + $('#bottom_expert_link').removeClass('hide'); + $('#bottom_expert_assister_link').removeClass('hide'); }); -}) -$(document).on('click', '.name_search_only', function() { - $('#help_list').addClass('hide') - $('#help_search').removeClass('hide') - $('#help_type').html(this.id) - $('#back_to_help').removeClass('hide') -}) -$(document).on('click', '[data-target="#help_with_plan_shopping"]',function(){$('.help_reset').addClass("hide"); $('#help_list').removeClass("hide"); $('#back_to_help').addClass("hide"); $('#bottom_expert_link').removeClass("hide"); $('#bottom_expert_assister_link').removeClass("hide") }) + $(document).on('click', '#back_to_help', function () { + $('.help_reset').addClass('hide'); + $('#back_to_help').addClass('hide'); + $('#help_list').removeClass('hide'); + $('#help_status').html(''); + $('#help_sign_up_title').removeClass('hide'); + $('#help_from_expert_title').addClass('hide'); + }); + + function applyMyExpertSuccess(helperType, status) { + var form = document.getElementById('inbox_provider_form'); + if (form) form.style.display = 'none'; + + var tab = document.querySelector('#active_' + helperType + '_tab'); + if (!tab) return; + + var alertEl = tab.querySelector('.alert'); + if (alertEl) { + alertEl.classList.remove('alert-warning'); + alertEl.classList.add('alert-success'); + } + var iconEl = tab.querySelector('.icon'); + if (iconEl) { + iconEl.classList.remove('warning-icon'); + iconEl.classList.add('success-icon'); + } + var bodyEl = tab.querySelector('.warning-body'); + if (bodyEl) bodyEl.textContent = status; + + document.querySelectorAll('a.go-to-expert, button').forEach(function (el) { + el.classList.remove('hidden'); + el.classList.remove('hide'); + }); + tab.querySelectorAll('button').forEach(function (el) { + el.classList.add('hide'); + }); + } + + document.addEventListener('click', function (event) { + var trigger = event.target.closest('.select-broker, .select-assister'); + if (!trigger) return; + + var disableSelector = trigger.classList.contains('select-assister') ? '.select-assister' : '.select-broker'; + document.querySelectorAll(disableSelector).forEach(function (el) { + el.classList.add('disabled'); + }); -$(document).on('click', '#back_to_help', function(){ - $('.help_reset').addClass("hide"); - $("#back_to_help").addClass('hide'); - $('#help_list').removeClass("hide"); - $('#help_status').html('') - $('#help_sign_up_title').removeClass('hide'); - $('#help_from_expert_title').addClass('hide'); -}) + var helperType = trigger.getAttribute('data-assister') ? 'assister' : 'broker'; + var query = personPayloadSearchParams([ + ['my_expert', 'true'], + ['assister', trigger.getAttribute('data-assister') || ''], + ['broker', trigger.getAttribute('data-broker') || ''] + ]); -$(document).on('click', '.select-broker', function(){ - $('.select-broker').addClass('disabled'); - var helper_type = this.getAttribute('data-assister') ? "assister" : "broker"; - $.ajax({ - type: 'GET', - data: {assister: this.getAttribute('data-assister'), broker: this.getAttribute('data-broker'), - person: $('#help_requestor').html(), email: $('#help_requestor_email').html(), - first_name: $('#person_first_name').val(), last_name: $('#person_last_name').val(), - ssn: $('#person_ssn').val(), dob: $('#jq_datepicker_ignore_person_dob').val() - }, - url: '/exchanges/hbx_profiles/request_help.html?my_expert=true', - }).done(function(response) { - broker_status = JSON.parse(response); - var status = broker_status['status'] - $('#inbox_provider_form').hide(); - $('#active_'+helper_type+'_tab .alert').removeClass('alert-warning').addClass('alert-success') - $('#active_'+helper_type+'_tab .icon').removeClass('warning-icon').addClass('success-icon') - $('#active_'+helper_type+'_tab .warning-body').text(status) - $('a.go-to-expert, button').removeClass('hidden').removeClass('hide'); - $("#active_"+helper_type+"_tab button").addClass('hide') + fetch(REQUEST_HELP + query.toString(), { + method: 'GET', + headers: { 'X-Requested-With': 'XMLHttpRequest' }, + credentials: 'same-origin' + }) + .then(function (response) { + return response.text(); + }) + .then(function (responseText) { + applyMyExpertSuccess(helperType, JSON.parse(responseText).status); + }); }); -}) +})(jQuery); diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 90456b92810..38d19bb9e14 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -201,11 +201,11 @@ def broker_match?(user_person, writing_agent_id) def assister_match?(user_person, assister_agency_account) return false if assister_agency_account.blank? - writing_agent_id = assister_agency_account.writing_agent_id - return false if writing_agent_id.blank? + profile_id = assister_agency_account.benefit_sponsors_assister_agency_profile_id + return false if profile_id.blank? - user_person.assister_role&.active? && - user_person.assister_role.id == writing_agent_id + user_person.assister_role&.active? && user_person.assister_role.benefit_sponsors_assister_agency_profile_id == profile_id || + (user_person.assister_agency_staff_roles.active.any? { |staff| staff.benefit_sponsors_assister_agency_profile_id == profile_id }) end def redirect_if_prod diff --git a/app/controllers/exchanges/hbx_profiles_controller.rb b/app/controllers/exchanges/hbx_profiles_controller.rb index 96b90dd8967..09eb1ed3597 100644 --- a/app/controllers/exchanges/hbx_profiles_controller.rb +++ b/app/controllers/exchanges/hbx_profiles_controller.rb @@ -339,7 +339,7 @@ def request_help assister_role_id = agent.assister_role.id consumer = Person.find(params[:person]) family = consumer.primary_family - authorize family, :hire_broker_agency? + authorize family, :hire_assister_agency? family.hire_assister_agency(assister_role_id) role = l10n("assister") end diff --git a/app/controllers/insured/families_controller.rb b/app/controllers/insured/families_controller.rb index abf7e8b1a25..b20885a1dea 100644 --- a/app/controllers/insured/families_controller.rb +++ b/app/controllers/insured/families_controller.rb @@ -525,11 +525,17 @@ def delete_consumer_broker else redirect_to :action => "home", flash: {notice: "Unable to remove expert from this account"} end + rescue Pundit::NotAuthorizedError + redirect_back( + fallback_location: { action: "home" }, + allow_other_host: false, + flash: { error: l10n("not_authorized") } + ) end def delete_consumer_assister @family = Family.find(params[:id]) - authorize @family, :delete_consumer_broker? + authorize @family, :delete_consumer_assister? assister_agency = @family&.current_assister_agency @@ -539,6 +545,12 @@ def delete_consumer_assister else redirect_to :action => "home", flash: {notice: "Unable to remove expert from this account"} end + rescue Pundit::NotAuthorizedError + redirect_back( + fallback_location: { action: "home" }, + allow_other_host: false, + flash: { error: l10n("not_authorized") } + ) end def transition_family_members diff --git a/app/data_migrations/permissions/dc_define_permissions.rb b/app/data_migrations/permissions/dc_define_permissions.rb index 396a9a814ee..458160ddc58 100644 --- a/app/data_migrations/permissions/dc_define_permissions.rb +++ b/app/data_migrations/permissions/dc_define_permissions.rb @@ -394,5 +394,14 @@ def hbx_admin_can_edit_notice_templates Permission.hbx_staff.update_attributes!(can_edit_notice_templates: true) Permission.hbx_tier3.update_attributes!(can_edit_notice_templates: true) end + + def hbx_admin_can_create_assister_agency + Permission.hbx_staff.update_attributes!(can_create_assister_agency: true) + Permission.super_admin.update_attributes!(can_create_assister_agency: true) + Permission.hbx_tier3.update_attributes!(can_create_assister_agency: false) + Permission.hbx_csr_supervisor.update_attributes!(can_create_assister_agency: false) + Permission.hbx_csr_tier1.update_attributes!(can_create_assister_agency: false) + Permission.hbx_csr_tier2.update_attributes!(can_create_assister_agency: false) + end end # rubocop:enable Metrics/ClassLength diff --git a/app/data_migrations/permissions/me_define_permissions.rb b/app/data_migrations/permissions/me_define_permissions.rb index 32aa4b08e94..25d84cd79c2 100644 --- a/app/data_migrations/permissions/me_define_permissions.rb +++ b/app/data_migrations/permissions/me_define_permissions.rb @@ -438,6 +438,15 @@ def hbx_admin_can_reprint_tax_documents Permission.hbx_read_only.update_attributes!(can_reprint_tax_documents: false) end + def hbx_admin_can_create_assister_agency + Permission.hbx_staff.update_attributes!(can_create_assister_agency: true) + Permission.super_admin.update_attributes!(can_create_assister_agency: true) + Permission.hbx_tier3.update_attributes!(can_create_assister_agency: false) + Permission.hbx_csr_supervisor.update_attributes!(can_create_assister_agency: false) + Permission.hbx_csr_tier1.update_attributes!(can_create_assister_agency: false) + Permission.hbx_csr_tier2.update_attributes!(can_create_assister_agency: false) + end + def hbx_admin_can_view_notice_templates Permission.super_admin.update_attributes!(can_view_notice_templates: true) Permission.hbx_staff.update_attributes!(can_view_notice_templates: true) diff --git a/app/models/permission.rb b/app/models/permission.rb index 1a47def4ed0..c54921b75f9 100644 --- a/app/models/permission.rb +++ b/app/models/permission.rb @@ -68,6 +68,7 @@ class Permission field :can_edit_notice_templates, type: Boolean, default: false field :can_view_audit_log, type: Boolean, default: false field :can_reprint_tax_documents, type: Boolean, default: false + field :can_create_assister_agency, type: Boolean, default: false class << self def hbx_staff diff --git a/app/policies/application_policy.rb b/app/policies/application_policy.rb index e90786cb25a..e5b4203665e 100644 --- a/app/policies/application_policy.rb +++ b/app/policies/application_policy.rb @@ -216,8 +216,7 @@ def active_associated_individual_market_family_assister? assister_agency_account = family&.active_assister_agency_account return false if assister_agency_account.blank? - assister_agency_account.benefit_sponsors_assister_agency_profile_id == assister.benefit_sponsors_assister_agency_profile_id && - assister_agency_account.writing_agent_id == assister.id + assister_agency_account.benefit_sponsors_assister_agency_profile_id == assister.benefit_sponsors_assister_agency_profile_id end # Determines if the current user is an admin in the individual market. @@ -282,8 +281,7 @@ def active_associated_coverall_market_family_assister? assister_agency_account = family.active_assister_agency_account return false if assister_agency_account.blank? - assister_agency_account.benefit_sponsors_assister_agency_profile_id == assister.benefit_sponsors_assister_agency_profile_id && - assister_agency_account.writing_agent_id == assister.id + assister_agency_account.benefit_sponsors_assister_agency_profile_id == assister.benefit_sponsors_assister_agency_profile_id end # Checks if the account holder is an admin in the coverall market. diff --git a/app/policies/family_policy.rb b/app/policies/family_policy.rb index 2dd441b2929..ccbadbb5047 100644 --- a/app/policies/family_policy.rb +++ b/app/policies/family_policy.rb @@ -262,6 +262,7 @@ def delete_consumer_broker? def delete_consumer_assister? return true if individual_market_primary_family_member? + return true if individual_market_non_ridp_primary_family_member? return true if individual_market_admin? return true if shop_market_primary_family_member? diff --git a/app/views/exchanges/bulk_notices/preview.html.erb b/app/views/exchanges/bulk_notices/preview.html.erb index ec1c7741a0e..b42482f0341 100644 --- a/app/views/exchanges/bulk_notices/preview.html.erb +++ b/app/views/exchanges/bulk_notices/preview.html.erb @@ -66,7 +66,7 @@ Important:
<%= l10n("admin_actions.bulk_upload.new.description_sub_text") %>
<%= form_for(@bulk_notice, url: exchanges_bulk_notice_path(@bulk_notice)) do |f| %> - <%= f.select :audience_type, { 'Broker Agency' => :broker_agency, 'Assister Agency' => :assister_agency, 'Employer' => :employer, 'General Agency' => :general_agency, 'Employee' => :employee }, { selected: @bulk_notice.audience_type }, class: 'form-control col-2', data: { reflex: 'change->BulkNotice#audience_select' } %> + <%= f.select :audience_type, { 'Broker Agency' => :broker_agency, 'Assister Organization' => :assister_agency, 'Employer' => :employer, 'General Agency' => :general_agency, 'Employee' => :employee }, { selected: @bulk_notice.audience_type }, class: 'form-control col-2', data: { reflex: 'change->BulkNotice#audience_select' } %>