From cb48510567175105390d635f32eb17388a1ac305 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Meny?= Date: Fri, 8 Jul 2022 13:31:30 +0100 Subject: [PATCH] Scheme import complete (Management Groups) --- app/services/imports/scheme_import_service.rb | 51 ++++++++++++--- .../imports/scheme_location_import_service.rb | 2 +- ...0708112603_add_missing_fields_to_scheme.rb | 9 +++ db/schema.rb | 9 ++- ...e7ad6dc0f1cf7ef33c18cc8c108bebc1b4923e.xml | 25 ++++++++ ...b3836b70b4dd9903263d5a764a5c45b964a89d.xml | 23 +++++++ ...6d7618b58affe2a150a5ef2e9f4765fa6cd05d.xml | 9 +++ .../imports/scheme_import_service_spec.rb | 63 +++++++++++++++++++ 8 files changed, 180 insertions(+), 11 deletions(-) create mode 100644 db/migrate/20220708112603_add_missing_fields_to_scheme.rb create mode 100644 spec/fixtures/imports/scheme_locations/0ae7ad6dc0f1cf7ef33c18cc8c108bebc1b4923e.xml create mode 100644 spec/fixtures/imports/scheme_locations/0bb3836b70b4dd9903263d5a764a5c45b964a89d.xml create mode 100644 spec/fixtures/imports/schemes/6d6d7618b58affe2a150a5ef2e9f4765fa6cd05d.xml create mode 100644 spec/services/imports/scheme_import_service_spec.rb diff --git a/app/services/imports/scheme_import_service.rb b/app/services/imports/scheme_import_service.rb index 42289d45f..c045d1e2f 100644 --- a/app/services/imports/scheme_import_service.rb +++ b/app/services/imports/scheme_import_service.rb @@ -4,21 +4,58 @@ module Imports import_from(folder, :create_scheme) end - private - def create_scheme(xml_document) - old_visible_id = scheme_field_value(xml_document, "visible-id") + old_id = string_or_nil(xml_document, "id") + status = string_or_nil(xml_document, "status") + + return unless status == "Approved" + Scheme.create!( - old_id: scheme_field_value(xml_document, "id"), - old_visible_id: + owning_organisation_id: find_owning_organisation_id(xml_document), + managing_organisation_id: find_managing_organisation_id(xml_document), + service_name: string_or_nil(xml_document, "name"), + arrangement_type: string_or_nil(xml_document, "arrangement_type"), + old_id:, + old_visible_id: safe_string_as_integer(xml_document, "visible-id"), ) rescue ActiveRecord::RecordNotUnique - name = scheme_field_value(xml_document, "name") - @logger.warn("Scheme #{name} is already present with old visible ID #{old_visible_id}, skipping.") + name = string_or_nil(xml_document, "name") + @logger.warn("Scheme #{name} is already present with legacy ID #{old_id}, skipping.") end + private + def scheme_field_value(xml_document, field) field_value(xml_document, "mgmtgroup", field) end + + def string_or_nil(xml_doc, attribute) + str = scheme_field_value(xml_doc, attribute) + str.presence + end + + # Safe: A string that represents only an integer (or empty/nil) + def safe_string_as_integer(xml_doc, attribute) + str = scheme_field_value(xml_doc, attribute) + Integer(str, exception: false) + end + + def find_owning_organisation_id(xml_doc) + old_org_id = string_or_nil(xml_doc, "institution") + organisation = Organisation.find_by(old_org_id:) + raise "Organisation not found with legacy ID #{old_org_id}" if organisation.nil? + + organisation.id + end + + def find_managing_organisation_id(xml_doc) + old_visible_id = safe_string_as_integer(xml_doc, "agent") + return unless old_visible_id + + organisation = Organisation.find_by(old_visible_id:) + raise "Organisation not found with legacy visible ID #{old_visible_id}" if organisation.nil? + + organisation.id + end end end diff --git a/app/services/imports/scheme_location_import_service.rb b/app/services/imports/scheme_location_import_service.rb index f740d8126..31689c761 100644 --- a/app/services/imports/scheme_location_import_service.rb +++ b/app/services/imports/scheme_location_import_service.rb @@ -10,7 +10,7 @@ module Imports old_visible_id = location_field_value(xml_document, "visible-id") Scheme.create!( old_id: location_field_value(xml_document, "id"), - old_visible_id: + old_visible_id:, ) rescue ActiveRecord::RecordNotUnique name = location_field_value(xml_document, "name") diff --git a/db/migrate/20220708112603_add_missing_fields_to_scheme.rb b/db/migrate/20220708112603_add_missing_fields_to_scheme.rb new file mode 100644 index 000000000..82669a5b2 --- /dev/null +++ b/db/migrate/20220708112603_add_missing_fields_to_scheme.rb @@ -0,0 +1,9 @@ +class AddMissingFieldsToScheme < ActiveRecord::Migration[7.0] + def change + change_table :schemes, bulk: true do |t| + t.column :arrangement_type, :string + t.column :old_id, :string + t.column :old_visible_id, :integer + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 429738353..a34ffb64a 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: 2022_07_05_130923) do +ActiveRecord::Schema[7.0].define(version: 2022_07_08_112603) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -191,9 +191,9 @@ ActiveRecord::Schema[7.0].define(version: 2022_07_05_130923) do t.integer "joint" t.bigint "created_by_id" t.integer "illness_type_0" - t.integer "retirement_value_check" t.integer "tshortfall_known" t.integer "sheltered" + t.integer "retirement_value_check" t.integer "pregnancy_value_check" t.integer "hhtype" t.integer "new_old" @@ -253,7 +253,7 @@ ActiveRecord::Schema[7.0].define(version: 2022_07_05_130923) do create_table "logs_exports", force: :cascade do |t| t.datetime "created_at", default: -> { "CURRENT_TIMESTAMP" } - t.datetime "started_at", null: false + t.datetime "started_at", precision: nil, null: false t.integer "base_number", default: 1, null: false t.integer "increment_number", default: 1, null: false t.boolean "empty_export", default: false, null: false @@ -313,6 +313,9 @@ ActiveRecord::Schema[7.0].define(version: 2022_07_05_130923) do t.datetime "end_date" t.integer "has_other_client_group" t.bigint "managing_organisation_id" + t.string "arrangement_type" + t.string "old_id" + t.integer "old_visible_id" t.index ["managing_organisation_id"], name: "index_schemes_on_managing_organisation_id" t.index ["owning_organisation_id"], name: "index_schemes_on_owning_organisation_id" end diff --git a/spec/fixtures/imports/scheme_locations/0ae7ad6dc0f1cf7ef33c18cc8c108bebc1b4923e.xml b/spec/fixtures/imports/scheme_locations/0ae7ad6dc0f1cf7ef33c18cc8c108bebc1b4923e.xml new file mode 100644 index 000000000..68eda865e --- /dev/null +++ b/spec/fixtures/imports/scheme_locations/0ae7ad6dc0f1cf7ef33c18cc8c108bebc1b4923e.xml @@ -0,0 +1,25 @@ + + 0ae7ad6dc0f1cf7ef33c18cc8c108bebc1b4923e + Location 1 + 134 + S44 6EJ + true + false + 5 + True + 7 + 6 + 1 + 2 + A + P + M + + 1900-01-01 + 2050-12-31 + 6d6d7618b58affe2a150a5ef2e9f4765fa6cd05d + Approved + 10 + 1 + 08:12.0 + diff --git a/spec/fixtures/imports/scheme_locations/0bb3836b70b4dd9903263d5a764a5c45b964a89d.xml b/spec/fixtures/imports/scheme_locations/0bb3836b70b4dd9903263d5a764a5c45b964a89d.xml new file mode 100644 index 000000000..260213b64 --- /dev/null +++ b/spec/fixtures/imports/scheme_locations/0bb3836b70b4dd9903263d5a764a5c45b964a89d.xml @@ -0,0 +1,23 @@ + + 0bb3836b70b4dd9903263d5a764a5c45b964a89d + Location 2 + 134 + NG19 8SW + false + false + 11 + 7 + 6 + 1 + 0 + W + False + P + M + + 2014-04-07 + + 6d6d7618b58affe2a150a5ef2e9f4765fa6cd05d + Approved + 001 + diff --git a/spec/fixtures/imports/schemes/6d6d7618b58affe2a150a5ef2e9f4765fa6cd05d.xml b/spec/fixtures/imports/schemes/6d6d7618b58affe2a150a5ef2e9f4765fa6cd05d.xml new file mode 100644 index 000000000..5a7b23b5b --- /dev/null +++ b/spec/fixtures/imports/schemes/6d6d7618b58affe2a150a5ef2e9f4765fa6cd05d.xml @@ -0,0 +1,9 @@ + + 6d6d7618b58affe2a150a5ef2e9f4765fa6cd05d + Management Group + O + 456 + 7c5bd5fb549c09z2c55d9cb90d7ba84927e64618 + Approved + 123 + diff --git a/spec/services/imports/scheme_import_service_spec.rb b/spec/services/imports/scheme_import_service_spec.rb new file mode 100644 index 000000000..518db62dc --- /dev/null +++ b/spec/services/imports/scheme_import_service_spec.rb @@ -0,0 +1,63 @@ +require "rails_helper" + +RSpec.describe Imports::SchemeImportService do + subject(:scheme_service) { described_class.new(storage_service, logger) } + + let(:storage_service) { instance_double(StorageService) } + let(:logger) { instance_double(ActiveSupport::Logger) } + + let(:fixture_directory) { "spec/fixtures/imports/schemes" } + let(:scheme_id) { "6d6d7618b58affe2a150a5ef2e9f4765fa6cd05d" } + + let!(:owning_org) { FactoryBot.create(:organisation, old_org_id: "7c5bd5fb549c09z2c55d9cb90d7ba84927e64618") } + let!(:managing_org) { FactoryBot.create(:organisation, old_visible_id: 456) } + + def open_file(directory, filename) + File.open("#{directory}/#{filename}.xml") + end + + context "when importing case logs" do + let(:remote_folder) { "mgmtgroups" } + + before do + # Stub the S3 file listing and download + allow(storage_service).to receive(:list_files) + .and_return(%W[#{remote_folder}/#{scheme_id}.xml]) + allow(storage_service).to receive(:get_file_io) + .with("#{remote_folder}/#{scheme_id}.xml") + .and_return(open_file(fixture_directory, scheme_id), open_file(fixture_directory, scheme_id)) + end + + it "successfully create all case logs" do + expect(logger).not_to receive(:error) + expect(logger).not_to receive(:warn) + expect(logger).not_to receive(:info) + expect { scheme_service.create_schemes(remote_folder) } + .to change(Scheme, :count).by(1) + end + end + + context "when importing a specific scheme" do + let(:scheme_file) { open_file(fixture_directory, scheme_id) } + let(:scheme_xml) { Nokogiri::XML(scheme_file) } + + it "matches expected values" do + scheme = scheme_service.create_scheme(scheme_xml) + expect(scheme.owning_organisation).to eq(owning_org) + expect(scheme.managing_organisation).to eq(managing_org) + expect(scheme.old_id).to eq("6d6d7618b58affe2a150a5ef2e9f4765fa6cd05d") + expect(scheme.old_visible_id).to eq(123) + expect(scheme.service_name).to eq("Management Group") + expect(scheme.arrangement_type).to eq("O") + end + + context "and the scheme status is not approved" do + before { scheme_xml.at_xpath("//mgmtgroup:status").content = "Temporary" } + + it "does not create the scheme" do + scheme = scheme_service.create_scheme(scheme_xml) + expect(scheme).to be_nil + end + end + end +end