From 4a00c987a9bb147346b6cee63fc977e3e4624d4a Mon Sep 17 00:00:00 2001 From: Leticia Errandonea Mattos Date: Tue, 30 Apr 2024 15:27:58 -0300 Subject: [PATCH] [#162263] Multi-Facility - 5c When an admin places a cross-core order, update valid payment source list (#4195) * Add controller action to get account options * Use new action to get accounts * Add TODO comment * Only facility admins have access to new action * Include blank option * Add spec * Code style updates * Return only necessary data * WIP: Improve spec * Use product facility instead of original order facility * Fix spec * Fix bug when there are not any accounts * Refactor * Rename var --- app/assets/javascripts/app/merge_orders.js | 57 +++++++++++++++---- .../facility_accounts_controller.rb | 21 +++++++ app/forms/add_to_order_form.rb | 4 +- app/lib/ability.rb | 4 ++ app/models/concerns/users/roles.rb | 4 ++ .../_merge_order_form.html.haml | 7 ++- config/routes.rb | 4 ++ spec/system/admin/adding_to_an_order_spec.rb | 3 + 8 files changed, 89 insertions(+), 15 deletions(-) diff --git a/app/assets/javascripts/app/merge_orders.js b/app/assets/javascripts/app/merge_orders.js index d60ce2805c..b6ba18e01c 100644 --- a/app/assets/javascripts/app/merge_orders.js +++ b/app/assets/javascripts/app/merge_orders.js @@ -44,32 +44,38 @@ window.MergeOrder = class MergeOrder { initCrossCoreOrdering() { if (!this.$form.length) { return; } - const product_field = this.$form.find(".js--edit-order__product"); - const facility_field = this.$form.find(".js--edit-order__facility"); + const productField = this.$form.find(".js--edit-order__product"); + const facilityField = this.$form.find(".js--edit-order__facility"); + const accountField = this.$form.find(".js--edit-order__account"); const button = this.$form.find(".js--edit-order__button"); - if (!facility_field || !button) return; + if (!facilityField || !button) return; const originalFacilityId = button.data("original-facility"); const defaultButtonText = button.data("default-button-text"); const crossCoreButtonText = button.data("cross-core-button-text"); - return facility_field.on("change", (event) => { + return facilityField.on("change", (event) => { const selectedElement = $(event.target).find(":selected"); - const url = selectedElement.data("products-path"); + const productsUrl = selectedElement.data("products-path"); + const accountsUrl = selectedElement.data("accounts-path"); const originalOrderFacility = selectedElement.data("original-order-facility"); + const originalOrder = selectedElement.data("original-order"); const facility_id = $(event.target).val(); + const includeBlank = JSON.parse( + accountField.data("include-blank") + ); - return $.ajax({ + $.ajax({ type: "get", data: { facility_id, original_order_facility: originalOrderFacility }, - url, + url: productsUrl, success(data) { // Populate dropdown - product_field.empty(); + productField.empty(); data = JSON.parse(data); data.forEach(function (product) { - return product_field.append( + return productField.append( ''); + } + + data.forEach(function (account) { + return accountField.append( + '" + ); + }); + + accountField.trigger("chosen:updated"); + + return accountField.trigger("change"); }, }); }); diff --git a/app/controllers/facility_accounts_controller.rb b/app/controllers/facility_accounts_controller.rb index 49b864aafc..ca60b5b398 100644 --- a/app/controllers/facility_accounts_controller.rb +++ b/app/controllers/facility_accounts_controller.rb @@ -12,6 +12,7 @@ class FacilityAccountsController < ApplicationController before_action :init_current_facility before_action :init_account, except: :search_results before_action :build_account, only: [:new, :create] + before_action :set_facility_accounts_for_user, only: [:accounts_available_for_order] authorize_resource :account @@ -119,6 +120,14 @@ def show_statement end end + def accounts_available_for_order + respond_to do |format| + format.js do + render json: @facility_accounts_for_user + end + end + end + private def available_account_types @@ -158,4 +167,16 @@ def build_account ).build end + def set_facility_accounts_for_user + order_id = params[:order_id] + order = Order.find(order_id) if order_id + + if order + order_user = order.user + @facility_accounts_for_user = AvailableAccountsFinder.new(order_user, current_facility).accounts.map { |a| { id: a.id, label: a.to_s } } + else + @facility_accounts_for_user = [] + end + end + end diff --git a/app/forms/add_to_order_form.rb b/app/forms/add_to_order_form.rb index ba8dd685c9..5ad4680339 100644 --- a/app/forms/add_to_order_form.rb +++ b/app/forms/add_to_order_form.rb @@ -80,7 +80,7 @@ def account end def available_accounts - AvailableAccountsFinder.new(original_order.user, current_facility) + AvailableAccountsFinder.new(original_order.user, product_facility) end def facilities_options @@ -90,7 +90,9 @@ def facilities_options f.id, { "data-products-path": Rails.application.routes.url_helpers.available_for_cross_core_ordering_facility_products_path(f, format: :js), + "data-accounts-path": Rails.application.routes.url_helpers.accounts_available_for_order_facility_accounts_path(f, format: :js), "data-original-order-facility": @original_order.facility_id, + "data-original-order": @original_order.id, } ] end diff --git a/app/lib/ability.rb b/app/lib/ability.rb index ae5f65408e..bbf8a2e270 100644 --- a/app/lib/ability.rb +++ b/app/lib/ability.rb @@ -168,6 +168,10 @@ def facility_director_abilities(user, resource, controller) def facility_administrator_abilities(user, resource, controller) can :available_for_cross_core_ordering, Product if controller.is_a?(ProductsController) + if controller.is_a?(FacilityAccountsController) && user.facility_administrator_of_any_facility? + can [:accounts_available_for_order, :show], Account + end + if resource.is_a?(PriceGroup) && user.facility_administrator_of?(resource.facility) if !resource.global? can :manage, [AccountPriceGroupMember, UserPriceGroupMember] diff --git a/app/models/concerns/users/roles.rb b/app/models/concerns/users/roles.rb index fb69300f2f..6892725487 100644 --- a/app/models/concerns/users/roles.rb +++ b/app/models/concerns/users/roles.rb @@ -33,6 +33,10 @@ def operable_facilities end end + def facility_administrator_of_any_facility? + user_roles.find { |r| r.role == UserRole::FACILITY_ADMINISTRATOR }.present? + end + # Returns relation of facilities for which this user is a director or admin def manageable_facilities if administrator? || global_billing_administrator? diff --git a/app/views/facility_orders/_merge_order_form.html.haml b/app/views/facility_orders/_merge_order_form.html.haml index 6fdc3e5345..bb04c2cf78 100644 --- a/app/views/facility_orders/_merge_order_form.html.haml +++ b/app/views/facility_orders/_merge_order_form.html.haml @@ -1,7 +1,8 @@ - if @merge_orders.blank? .well = simple_form_for [current_facility, @add_to_order_form], url: facility_order_path(current_facility, @order), method: :put, html: { class: "js--edit-order" } do |f| - - if SettingsHelper.feature_on?(:cross_core_projects) && can?(:available_for_cross_core_ordering, Product) + - enable_cross_core_changes = SettingsHelper.feature_on?(:cross_core_projects) && can?(:available_for_cross_core_ordering, Product) + - if enable_cross_core_changes = f.label :facility_id, Facility.model_name.human = f.input_field :facility_id, collection: @add_to_order_form.facilities_options, @@ -31,12 +32,12 @@ input_html: { class: "js--chosen" }, include_blank: false, label: OrderDetail.human_attribute_name(:order_status) + - input_html = enable_cross_core_changes ? { class: "js--edit-order__account js--chosen", data: { "include-blank" => !@order.account.active? } } : { class: "js--chosen" } = f.input :account_id, collection: @add_to_order_form.available_accounts, include_blank: !@order.account.active?, hint: @order.account.active? ? "" : t(".original_account_inactive", account: @order.account), - input_html: { class: "js--chosen" } - + input_html: input_html = f.input_field :fulfilled_at, placeholder: OrderDetail.human_attribute_name(:fulfilled_at), diff --git a/config/routes.rb b/config/routes.rb index 20254ccade..9dbfdb2d1d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -288,6 +288,10 @@ end resources :orders, controller: "facility_account_orders", only: [:index] + + collection do + get :accounts_available_for_order + end end ###### diff --git a/spec/system/admin/adding_to_an_order_spec.rb b/spec/system/admin/adding_to_an_order_spec.rb index 37d3ddde03..b06951db34 100644 --- a/spec/system/admin/adding_to_an_order_spec.rb +++ b/spec/system/admin/adding_to_an_order_spec.rb @@ -306,6 +306,7 @@ context "with admin role" do let(:user) { create(:user, :facility_administrator, facility:) } + let!(:facility2_account) { create(:account, :with_account_owner, type: "CreditCardAccount", owner: order.user, description: "Other Account", facility: facility2) } it "changes the button text" do expect(page).to have_button("Add To Order") @@ -318,9 +319,11 @@ expect(page).not_to have_content("Cross Core Project ID") expect(page.has_selector?("option", text: cross_core_product_facility.name, visible: false)).to be(true) expect(page.has_selector?("option", text: product.name, visible: false)).to be(true) + expect(page.has_selector?("option", text: facility2_account.to_s, visible: false)).to be(false) select_from_chosen facility2.name, from: "add_to_order_form[facility_id]" select_from_chosen cross_core_product_facility2.name, from: "add_to_order_form[product_id]" + select_from_chosen facility2_account.to_s, from: "Payment Source" expect(page.has_selector?("option", text: product2.name, visible: false)).to be(false)