From dd9fbd70ccdb368cce6db86600824509a1de1ab4 Mon Sep 17 00:00:00 2001 From: Joaquin Correa Date: Mon, 13 Jan 2025 15:28:13 -0300 Subject: [PATCH 1/7] Add sanger enabled to product --- .../20250110132703_add_product_sanger_sequencing_enabled.rb | 5 +++++ db/schema.rb | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20250110132703_add_product_sanger_sequencing_enabled.rb diff --git a/db/migrate/20250110132703_add_product_sanger_sequencing_enabled.rb b/db/migrate/20250110132703_add_product_sanger_sequencing_enabled.rb new file mode 100644 index 0000000000..589e4713cf --- /dev/null +++ b/db/migrate/20250110132703_add_product_sanger_sequencing_enabled.rb @@ -0,0 +1,5 @@ +class AddProductSangerSequencingEnabled < ActiveRecord::Migration[7.0] + def change + add_column :products, :sanger_sequencing_enabled, :boolean, null: false, default: false + end +end diff --git a/db/schema.rb b/db/schema.rb index d361f726a8..5669d36e76 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.0].define(version: 2024_12_12_185208) do +ActiveRecord::Schema[7.0].define(version: 2025_01_10_132703) do create_table "account_facility_joins", id: :integer, charset: "utf8mb3", force: :cascade do |t| t.integer "facility_id", null: false t.integer "account_id", null: false @@ -664,6 +664,7 @@ t.integer "min_reserve_days" t.integer "max_reserve_days" t.boolean "start_time_disabled", default: false, null: false + t.boolean "sanger_sequencing_enabled", default: false, null: false t.index ["dashboard_token"], name: "index_products_on_dashboard_token" t.index ["facility_account_id"], name: "fk_facility_accounts" t.index ["facility_id"], name: "fk_rails_0c9fa1afbe" From f1748729b1357de88714866982cafe25de1d3c15 Mon Sep 17 00:00:00 2001 From: Joaquin Correa Date: Mon, 13 Jan 2025 15:32:40 -0300 Subject: [PATCH 2/7] Handle service sanger enable/disable --- app/controllers/services_controller.rb | 47 +++++++++++++++++++ .../external_services/external_service.rb | 4 +- app/views/services/_service_fields.html.haml | 6 +++ .../services/_service_manage_fields.html.haml | 2 + config/locales/en.controllers.yml | 4 ++ config/locales/en.models.yml | 2 + config/locales/en.yml | 5 ++ 7 files changed, 69 insertions(+), 1 deletion(-) create mode 100644 app/views/services/_service_fields.html.haml create mode 100644 app/views/services/_service_manage_fields.html.haml diff --git a/app/controllers/services_controller.rb b/app/controllers/services_controller.rb index 84f4288edc..af2f6ca987 100644 --- a/app/controllers/services_controller.rb +++ b/app/controllers/services_controller.rb @@ -1,4 +1,51 @@ # frozen_string_literal: true class ServicesController < ProductsCommonController + after_action :update_sanger_external_service, only: [:create, :update] + + private + + def permitted_params + params = super + + if current_facility.sanger_sequencing_enabled? + params += %i[sanger_sequencing_enabled] + end + + params + end + + def update_sanger_external_service + return unless @product.sanger_sequencing_enabled_previously_changed? + + if @product.sanger_sequencing_enabled? + ensure_sanger_url_service + flash[:info] = t("controllers.services.sanger_sequencing_enabled") + else + flash[:info] = t("controllers.services.sanger_sequencing_disabled") + end + end + + ## + # Ensures UrlService exists for the product + # pointing to Sanger Submission + def ensure_sanger_url_service + sanger_external_service = + @product + .external_services + .matching_location(new_sanger_sequencing_submission_path) + .first + + if sanger_external_service.blank? + Service.transaction do + external_service = UrlService.find_or_create_by( + location: new_sanger_sequencing_submission_path + ) + ExternalServicePasser.create!( + external_service:, + passer: @product, + ) + end + end + end end diff --git a/app/models/external_services/external_service.rb b/app/models/external_services/external_service.rb index fd819c368c..f937ee9686 100644 --- a/app/models/external_services/external_service.rb +++ b/app/models/external_services/external_service.rb @@ -3,7 +3,9 @@ # # Represents a 3rd party service in use by the system class ExternalService < ApplicationRecord - validates_presence_of :location + def self.matching_location(value) + where("location like ?", "%#{value}%") + end end diff --git a/app/views/services/_service_fields.html.haml b/app/views/services/_service_fields.html.haml new file mode 100644 index 0000000000..30a32259c3 --- /dev/null +++ b/app/views/services/_service_fields.html.haml @@ -0,0 +1,6 @@ +- if current_facility.sanger_sequencing_enabled? + = f.input :sanger_sequencing_enabled, + as: :boolean, + label: false, + inline_label: Service.human_attribute_name(:sanger_sequencing_enabled), + hint: t("services.service_fields.sanger.instruct.sanger_sequencing_enabled") diff --git a/app/views/services/_service_manage_fields.html.haml b/app/views/services/_service_manage_fields.html.haml new file mode 100644 index 0000000000..c491c99d67 --- /dev/null +++ b/app/views/services/_service_manage_fields.html.haml @@ -0,0 +1,2 @@ +- if current_facility.sanger_sequencing_enabled? + = f.input :sanger_sequencing_enabled diff --git a/config/locales/en.controllers.yml b/config/locales/en.controllers.yml index 594ba438f0..d4a6ee8278 100644 --- a/config/locales/en.controllers.yml +++ b/config/locales/en.controllers.yml @@ -214,6 +214,10 @@ en: error: "Our apologies, but an error occurred while importing: %{error}" job_is_queued: "The bulk import is being processed. A report will be sent to %{email} when complete." + services: + sanger_sequencing_enabled: Sanger has been enabled, make sure the Order Form is inactive + sanger_sequencing_disabled: Sanger has been disabled, make sure the Order Form is active + schedule_rules: create: Schedule Rule was successfully created. update: Schedule Rule was successfully updated. diff --git a/config/locales/en.models.yml b/config/locales/en.models.yml index 744af156ac..ffcfa36262 100644 --- a/config/locales/en.models.yml +++ b/config/locales/en.models.yml @@ -322,6 +322,8 @@ en: unit_cost: Unit Cost unit_adjustment: Unit Adjustment unit_net_cost: Unit Net Cost + service: + sanger_sequencing_enabled: Sanger Enabled stored_file: file_file_size: File user_role: diff --git a/config/locales/en.yml b/config/locales/en.yml index ee9f12a903..4f23706cf8 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1258,6 +1258,11 @@ en: shared: Shared schedule hints: schedule: You may share a schedule with other products. Choose an exisiting schedule or use an unshared schedule. + services: + service_fields: + sanger: + instruct: + sanger_sequencing_enabled: Enable Sanger submissions for this service notifications: index: From 146ab4788c8693bdb3cb6e7fb99478d6b4b9cdf6 Mon Sep 17 00:00:00 2001 From: Joaquin Correa Date: Mon, 13 Jan 2025 16:06:39 -0300 Subject: [PATCH 3/7] Add create spec --- spec/system/admin/creating_a_service_spec.rb | 30 ++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/spec/system/admin/creating_a_service_spec.rb b/spec/system/admin/creating_a_service_spec.rb index b1d96ba908..ac8bf78021 100644 --- a/spec/system/admin/creating_a_service_spec.rb +++ b/spec/system/admin/creating_a_service_spec.rb @@ -62,4 +62,34 @@ context "when billing mode is Skip Review" do include_examples "creates a product with billing mode", "service", "Skip Review" end + + context "when sanger enable si checked" do + let(:service) { Service.last } + + it "does not show the checkbox if facility is not sanger enabled" do + expect(facility.sanger_sequencing_enabled).to be false + + visit new_facility_service_path(facility) + + expect(page).to_not have_field "service[sanger_sequencing_enabled]" + end + + it "can enable sanger on service if sanger is enabled for facility" do + facility.update(sanger_sequencing_enabled: true) + + visit new_facility_service_path(facility) + + fill_in "service[name]", with: "Sanger Sequencing" + fill_in "service[url_name]", with: "sanger-sequencing" + + check "service[sanger_sequencing_enabled]" + + click_button "Create" + + expect(page).to have_content("Service was successfully created") + expect(page).to have_content("Sanger has been enabled") + + expect(service.external_services.length).to eq(1) + end + end end From f8044af7307bbf68805604e80bd7ca90db281814 Mon Sep 17 00:00:00 2001 From: Joaquin Correa Date: Mon, 13 Jan 2025 17:26:34 -0300 Subject: [PATCH 4/7] Edit tests --- spec/system/admin/creating_a_service_spec.rb | 11 +--- spec/system/admin/editing_a_service_spec.rb | 60 ++++++++++++++++++++ 2 files changed, 62 insertions(+), 9 deletions(-) create mode 100644 spec/system/admin/editing_a_service_spec.rb diff --git a/spec/system/admin/creating_a_service_spec.rb b/spec/system/admin/creating_a_service_spec.rb index ac8bf78021..0a4c539218 100644 --- a/spec/system/admin/creating_a_service_spec.rb +++ b/spec/system/admin/creating_a_service_spec.rb @@ -9,7 +9,7 @@ let(:logged_in_user) { director } before { login_as logged_in_user } - it "can create and edit a service" do + it "can create a service" do visit facility_products_path(facility) click_link "Services (0)", exact: true click_link "Add Service" @@ -20,13 +20,6 @@ expect(current_path).to eq(manage_facility_service_path(facility, Service.last)) expect(page).to have_content("My New Service") - - click_link "Edit" - fill_in "service[description]", with: "Some description" - click_button "Save" - - expect(current_path).to eq(manage_facility_service_path(facility, Service.last)) - expect(page).to have_content("Some description") end it "can add order forms" do @@ -71,7 +64,7 @@ visit new_facility_service_path(facility) - expect(page).to_not have_field "service[sanger_sequencing_enabled]" + expect(page).to_not have_field("service[sanger_sequencing_enabled]") end it "can enable sanger on service if sanger is enabled for facility" do diff --git a/spec/system/admin/editing_a_service_spec.rb b/spec/system/admin/editing_a_service_spec.rb new file mode 100644 index 0000000000..11e2d210e9 --- /dev/null +++ b/spec/system/admin/editing_a_service_spec.rb @@ -0,0 +1,60 @@ +# frozen_string_literal: true + +require "rails_helper" + +RSpec.describe "Editing a Service" do + let(:facility) { create :setup_facility } + let(:service) { create :service, facility: } + let(:admin) { create :user, :administrator } + + before do + login_as admin + end + + it "can edit a service" do + visit edit_facility_service_path(facility, service) + + fill_in "service[description]", with: "Some description" + click_button "Save" + + expect(current_path).to eq(manage_facility_service_path(facility, Service.last)) + expect(page).to have_content("Some description") + end + + describe "sanger enable change" do + it "does not show sanger enable if facility is not sanger enabled" do + facility.update(sanger_sequencing_enabled: false) + + visit edit_facility_service_path(facility, service) + + expect(page).to_not have_field("service[sanger_sequencing_enabled]") + end + + context "when facility is sanger enabled" do + before do + facility.update(sanger_sequencing_enabled: true) + end + + it "can enable sanger for the service" do + visit edit_facility_service_path(facility, service) + + check "service[sanger_sequencing_enabled]" + click_button "Save" + + expect(page).to have_content("Service was successfully updated") + expect(page).to have_content("Sanger has been enabled") + end + + it "can disable sanger for the service" do + service.update(sanger_sequencing_enabled: true) + visit edit_facility_service_path(facility, service) + + uncheck "service[sanger_sequencing_enabled]" + click_button "Save" + + expect(page).to have_content("Service was successfully updated") + expect(page).to have_content("Sanger has been disabled") + end + end + end +end From de241849e7c106fd6538893791d2cb87f7b1f9a1 Mon Sep 17 00:00:00 2001 From: Joaquin Correa Date: Wed, 15 Jan 2025 10:17:55 -0300 Subject: [PATCH 5/7] Test UrlService creation --- app/controllers/file_uploads_controller.rb | 2 +- spec/controllers/services_controller_spec.rb | 27 ++++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/app/controllers/file_uploads_controller.rb b/app/controllers/file_uploads_controller.rb index 4207743a95..1b5c7d473a 100644 --- a/app/controllers/file_uploads_controller.rb +++ b/app/controllers/file_uploads_controller.rb @@ -169,7 +169,7 @@ def create_product_survey_from_url begin url = params[survey_param][:location] ext = UrlService.find_or_create_by(location: url) - esp = ExternalServicePasser.where(passer_id: @product.id, external_service_id: ext.id).first + esp = ExternalServicePasser.where(passer: @product, external_service_id: ext.id).first if esp @flash_notice = "That Online Order Form already exists" diff --git a/spec/controllers/services_controller_spec.rb b/spec/controllers/services_controller_spec.rb index b07ee1e1b1..39078238ba 100644 --- a/spec/controllers/services_controller_spec.rb +++ b/spec/controllers/services_controller_spec.rb @@ -105,6 +105,33 @@ is_expected.to set_flash assert_redirected_to manage_facility_service_url(@authable, assigns(:product)) end + + context "when sanger is enabled" do + before do + sign_in @admin + facility.update(sanger_sequencing_enabled: true) + @params[:service][:sanger_sequencing_enabled] = true + end + + it "creates an external service" do + expect { do_request }.to change { + @service.reload.external_services.count + }.by(1) + end + + it "does not create an external service if it already exists" do + ExternalServicePasser.create( + passer: @service, + external_service: UrlService.create( + location: new_sanger_sequencing_submission_path + ) + ) + + expect { do_request }.to_not change { + @service.reload.external_services.count + } + end + end end context "destroy" do From e1b54704cf8aaaeafa11ec8cb1d77b5387217038 Mon Sep 17 00:00:00 2001 From: Joaquin Correa Date: Wed, 15 Jan 2025 11:43:25 -0300 Subject: [PATCH 6/7] Handle sanger sequencing engine disabled --- app/controllers/services_controller.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/controllers/services_controller.rb b/app/controllers/services_controller.rb index af2f6ca987..e9a94536e3 100644 --- a/app/controllers/services_controller.rb +++ b/app/controllers/services_controller.rb @@ -30,6 +30,8 @@ def update_sanger_external_service # Ensures UrlService exists for the product # pointing to Sanger Submission def ensure_sanger_url_service + return unless defined? new_sanger_sequencing_submission_path + sanger_external_service = @product .external_services From 44bc0d843dab763ce577e43e0860e66c55c0f45b Mon Sep 17 00:00:00 2001 From: Joaquin Correa Date: Wed, 15 Jan 2025 17:15:31 -0300 Subject: [PATCH 7/7] Changes after review --- app/controllers/services_controller.rb | 2 +- config/locales/en.controllers.yml | 4 ++-- .../20250110132703_add_product_sanger_sequencing_enabled.rb | 2 ++ spec/system/admin/creating_a_service_spec.rb | 2 +- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/app/controllers/services_controller.rb b/app/controllers/services_controller.rb index e9a94536e3..6bf88bbb5c 100644 --- a/app/controllers/services_controller.rb +++ b/app/controllers/services_controller.rb @@ -41,7 +41,7 @@ def ensure_sanger_url_service if sanger_external_service.blank? Service.transaction do external_service = UrlService.find_or_create_by( - location: new_sanger_sequencing_submission_path + location: new_sanger_sequencing_submission_url ) ExternalServicePasser.create!( external_service:, diff --git a/config/locales/en.controllers.yml b/config/locales/en.controllers.yml index d4a6ee8278..6063f2035f 100644 --- a/config/locales/en.controllers.yml +++ b/config/locales/en.controllers.yml @@ -215,8 +215,8 @@ en: job_is_queued: "The bulk import is being processed. A report will be sent to %{email} when complete." services: - sanger_sequencing_enabled: Sanger has been enabled, make sure the Order Form is inactive - sanger_sequencing_disabled: Sanger has been disabled, make sure the Order Form is active + sanger_sequencing_enabled: Sanger has been enabled, make sure the Order Form is inactive. + sanger_sequencing_disabled: Sanger has been disabled, make sure the Order Form is active. schedule_rules: create: Schedule Rule was successfully created. diff --git a/db/migrate/20250110132703_add_product_sanger_sequencing_enabled.rb b/db/migrate/20250110132703_add_product_sanger_sequencing_enabled.rb index 589e4713cf..76c1b2d58d 100644 --- a/db/migrate/20250110132703_add_product_sanger_sequencing_enabled.rb +++ b/db/migrate/20250110132703_add_product_sanger_sequencing_enabled.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class AddProductSangerSequencingEnabled < ActiveRecord::Migration[7.0] def change add_column :products, :sanger_sequencing_enabled, :boolean, null: false, default: false diff --git a/spec/system/admin/creating_a_service_spec.rb b/spec/system/admin/creating_a_service_spec.rb index 0a4c539218..34867cbba8 100644 --- a/spec/system/admin/creating_a_service_spec.rb +++ b/spec/system/admin/creating_a_service_spec.rb @@ -56,7 +56,7 @@ include_examples "creates a product with billing mode", "service", "Skip Review" end - context "when sanger enable si checked" do + context "when sanger enable is checked" do let(:service) { Service.last } it "does not show the checkbox if facility is not sanger enabled" do