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