From 9acbc456991691bcfe3daf6ea427d91d6718ac62 Mon Sep 17 00:00:00 2001 From: Kat <54268893+kosiakkatrina@users.noreply.github.com> Date: Tue, 3 Dec 2024 11:35:31 +0000 Subject: [PATCH] Add sales export to the export service --- app/services/exports/export_service.rb | 13 +- .../exports/sales_log_export_service.rb | 5 + spec/services/exports/export_service_spec.rb | 246 +++++++++++++++++- 3 files changed, 257 insertions(+), 7 deletions(-) create mode 100644 app/services/exports/sales_log_export_service.rb diff --git a/app/services/exports/export_service.rb b/app/services/exports/export_service.rb index 40c10055b..bf0deb9ea 100644 --- a/app/services/exports/export_service.rb +++ b/app/services/exports/export_service.rb @@ -11,6 +11,7 @@ module Exports start_time = Time.zone.now daily_run_number = get_daily_run_number lettings_archives_for_manifest = {} + sales_archives_for_manifest = {} users_archives_for_manifest = {} organisations_archives_for_manifest = {} @@ -20,16 +21,19 @@ module Exports users_archives_for_manifest = get_user_archives(start_time, full_update) when "organisations" organisations_archives_for_manifest = get_organisation_archives(start_time, full_update) - else + when "lettings" lettings_archives_for_manifest = get_lettings_archives(start_time, full_update, year) + when "sales" + sales_archives_for_manifest = get_sales_archives(start_time, full_update, year) end else users_archives_for_manifest = get_user_archives(start_time, full_update) organisations_archives_for_manifest = get_organisation_archives(start_time, full_update) lettings_archives_for_manifest = get_lettings_archives(start_time, full_update, year) + sales_archives_for_manifest = get_sales_archives(start_time, full_update, year) if Time.zone.now >= Time.zone.local(2025, 4, 1) end - write_master_manifest(daily_run_number, lettings_archives_for_manifest.merge(users_archives_for_manifest).merge(organisations_archives_for_manifest)) + write_master_manifest(daily_run_number, lettings_archives_for_manifest.merge(sales_archives_for_manifest || {}).merge(users_archives_for_manifest).merge(organisations_archives_for_manifest)) end private @@ -74,5 +78,10 @@ module Exports lettings_export_service = Exports::LettingsLogExportService.new(@storage_service, start_time) lettings_export_service.export_xml_lettings_logs(full_update:, collection_year:) end + + def get_sales_archives(start_time, full_update, collection_year) + sales_export_service = Exports::SalesLogExportService.new(@storage_service, start_time) + sales_export_service.export_xml_sales_logs(full_update:, collection_year:) + end end end diff --git a/app/services/exports/sales_log_export_service.rb b/app/services/exports/sales_log_export_service.rb new file mode 100644 index 000000000..ad57c9c58 --- /dev/null +++ b/app/services/exports/sales_log_export_service.rb @@ -0,0 +1,5 @@ +module Exports + class SalesLogExportService < Exports::XmlExportService + def export_xml_sales_logs(full_update: false, collection_year: nil); end + end +end diff --git a/spec/services/exports/export_service_spec.rb b/spec/services/exports/export_service_spec.rb index fb52c5274..160c80a01 100644 --- a/spec/services/exports/export_service_spec.rb +++ b/spec/services/exports/export_service_spec.rb @@ -9,12 +9,14 @@ RSpec.describe Exports::ExportService do let(:user) { FactoryBot.create(:user, email: "test1@example.com") } let(:organisations_export_service) { instance_double("Exports::OrganisationExportService", export_xml_organisations: {}) } let(:users_export_service) { instance_double("Exports::UserExportService", export_xml_users: {}) } + let(:sales_logs_export_service) { instance_double("Exports::SalesLogExportService", export_xml_sales_logs: {}) } before do Timecop.freeze(start_time) Singleton.__init__(FormHandler) allow(storage_service).to receive(:write_file) allow(Exports::LettingsLogExportService).to receive(:new).and_return(lettings_logs_export_service) + allow(Exports::SalesLogExportService).to receive(:new).and_return(sales_logs_export_service) allow(Exports::UserExportService).to receive(:new).and_return(users_export_service) allow(Exports::OrganisationExportService).to receive(:new).and_return(organisations_export_service) end @@ -23,7 +25,7 @@ RSpec.describe Exports::ExportService do Timecop.return end - context "when exporting daily XMLs" do + context "when exporting daily XMLs before 2025" do context "and no lettings archives get created in lettings logs export" do let(:lettings_logs_export_service) { instance_double("Exports::LettingsLogExportService", export_xml_lettings_logs: {}) } @@ -193,6 +195,64 @@ RSpec.describe Exports::ExportService do end end end + + context "and multiple sales archives get created in sales logs export" do + let(:lettings_logs_export_service) { instance_double("Exports::LettingsLogExportService", export_xml_lettings_logs: { "some_file_base_name" => start_time, "second_file_base_name" => start_time }) } + let(:sales_logs_export_service) { instance_double("Exports::SalesLogExportService", export_xml_sales_logs: { "some_sales_file_base_name" => start_time, "second_sales_file_base_name" => start_time }) } + + context "and no user archives get created in user export" do + it "generates a master manifest with the correct name" do + expect(storage_service).to receive(:write_file).with(expected_master_manifest_filename, any_args) + export_service.export_xml + end + + it "generates a master manifest with CSV headers and correct data" do + actual_content = nil + expected_content = "zip-name,date-time zipped folder generated,zip-file-uri\nsome_file_base_name,2022-05-01 00:00:00 +0100,some_file_base_name.zip\nsecond_file_base_name,2022-05-01 00:00:00 +0100,second_file_base_name.zip\n" + allow(storage_service).to receive(:write_file).with(expected_master_manifest_filename, any_args) { |_, arg2| actual_content = arg2&.string } + + export_service.export_xml + expect(actual_content).to eq(expected_content) + end + end + + context "and multiple user archive gets created in user export" do + let(:users_export_service) { instance_double("Exports::UserExportService", export_xml_users: { "some_user_file_base_name" => start_time, "second_user_file_base_name" => start_time }) } + + it "generates a master manifest with the correct name" do + expect(storage_service).to receive(:write_file).with(expected_master_manifest_filename, any_args) + export_service.export_xml + end + + it "generates a master manifest with CSV headers and correct data" do + actual_content = nil + expected_content = "zip-name,date-time zipped folder generated,zip-file-uri\nsome_file_base_name,2022-05-01 00:00:00 +0100,some_file_base_name.zip\nsecond_file_base_name,2022-05-01 00:00:00 +0100,second_file_base_name.zip\nsome_user_file_base_name,2022-05-01 00:00:00 +0100,some_user_file_base_name.zip\nsecond_user_file_base_name,2022-05-01 00:00:00 +0100,second_user_file_base_name.zip\n" + allow(storage_service).to receive(:write_file).with(expected_master_manifest_filename, any_args) { |_, arg2| actual_content = arg2&.string } + + export_service.export_xml + expect(actual_content).to eq(expected_content) + end + end + + context "and multiple user and organisation archives gets created in user export" do + let(:users_export_service) { instance_double("Exports::UserExportService", export_xml_users: { "some_user_file_base_name" => start_time, "second_user_file_base_name" => start_time }) } + let(:organisations_export_service) { instance_double("Exports::OrganisationExportService", export_xml_organisations: { "some_organisation_file_base_name" => start_time, "second_organisation_file_base_name" => start_time }) } + + it "generates a master manifest with the correct name" do + expect(storage_service).to receive(:write_file).with(expected_master_manifest_filename, any_args) + export_service.export_xml + end + + it "generates a master manifest with CSV headers and correct data" do + actual_content = nil + expected_content = "zip-name,date-time zipped folder generated,zip-file-uri\nsome_file_base_name,2022-05-01 00:00:00 +0100,some_file_base_name.zip\nsecond_file_base_name,2022-05-01 00:00:00 +0100,second_file_base_name.zip\nsome_user_file_base_name,2022-05-01 00:00:00 +0100,some_user_file_base_name.zip\nsecond_user_file_base_name,2022-05-01 00:00:00 +0100,second_user_file_base_name.zip\nsome_organisation_file_base_name,2022-05-01 00:00:00 +0100,some_organisation_file_base_name.zip\nsecond_organisation_file_base_name,2022-05-01 00:00:00 +0100,second_organisation_file_base_name.zip\n" + allow(storage_service).to receive(:write_file).with(expected_master_manifest_filename, any_args) { |_, arg2| actual_content = arg2&.string } + + export_service.export_xml + expect(actual_content).to eq(expected_content) + end + end + end end context "when exporting specific lettings log collection" do @@ -204,7 +264,7 @@ RSpec.describe Exports::ExportService do it "generates a master manifest with the correct name" do expect(storage_service).to receive(:write_file).with(expected_master_manifest_filename, any_args) - export_service.export_xml(full_update: true, collection: "2022") + export_service.export_xml(full_update: true, collection: "lettings", year: "2022") end it "does not write user data" do @@ -212,7 +272,7 @@ RSpec.describe Exports::ExportService do expected_content = "zip-name,date-time zipped folder generated,zip-file-uri\n" allow(storage_service).to receive(:write_file).with(expected_master_manifest_filename, any_args) { |_, arg2| actual_content = arg2&.string } - export_service.export_xml(full_update: true, collection: "2022") + export_service.export_xml(full_update: true, collection: "lettings", year: "2022") expect(actual_content).to eq(expected_content) end end @@ -226,7 +286,7 @@ RSpec.describe Exports::ExportService do it "generates a master manifest with the correct name" do expect(storage_service).to receive(:write_file).with(expected_master_manifest_filename, any_args) - export_service.export_xml(full_update: true, collection: "2023") + export_service.export_xml(full_update: true, collection: "lettings", year: "2023") end it "does not write user data" do @@ -234,7 +294,7 @@ RSpec.describe Exports::ExportService do expected_content = "zip-name,date-time zipped folder generated,zip-file-uri\nsome_file_base_name,2022-05-01 00:00:00 +0100,some_file_base_name.zip\n" allow(storage_service).to receive(:write_file).with(expected_master_manifest_filename, any_args) { |_, arg2| actual_content = arg2&.string } - export_service.export_xml(full_update: true, collection: "2023") + export_service.export_xml(full_update: true, collection: "lettings", year: "2023") expect(actual_content).to eq(expected_content) end end @@ -330,4 +390,180 @@ RSpec.describe Exports::ExportService do end end end + + context "with date after 2025-04-01" do + let(:start_time) { Time.zone.local(2025, 5, 1) } + let(:expected_master_manifest_filename) { "Manifest_2025_05_01_0001.csv" } + let(:lettings_logs_export_service) { instance_double("Exports::LettingsLogExportService", export_xml_lettings_logs: {}) } + + context "when exporting daily XMLs" do + context "and no sales archives get created in sales logs export" do + let(:sales_logs_export_service) { instance_double("Exports::SalesLogExportService", export_xml_sales_logs: {}) } + let(:lettings_logs_export_service) { instance_double("Exports::LettingsLogExportService", export_xml_lettings_logs: {}) } + + context "and no user or organisation archives get created in user export" do + it "generates a master manifest with the correct name" do + expect(storage_service).to receive(:write_file).with(expected_master_manifest_filename, any_args) + export_service.export_xml + end + + it "generates a master manifest with CSV headers but no data" do + actual_content = nil + expected_content = "zip-name,date-time zipped folder generated,zip-file-uri\n" + allow(storage_service).to receive(:write_file).with(expected_master_manifest_filename, any_args) { |_, arg2| actual_content = arg2&.string } + + export_service.export_xml + expect(actual_content).to eq(expected_content) + end + end + end + + context "and one sales archive gets created in sales logs export" do + let(:sales_logs_export_service) { instance_double("Exports::SalesLogExportService", export_xml_sales_logs: { "some_sales_file_base_name" => start_time }) } + let(:lettings_logs_export_service) { instance_double("Exports::LettingsLogExportService", export_xml_lettings_logs: { "some_file_base_name" => start_time }) } + + context "and no user archives get created in user export" do + it "generates a master manifest with the correct name" do + expect(storage_service).to receive(:write_file).with(expected_master_manifest_filename, any_args) + export_service.export_xml + end + + it "generates a master manifest with CSV headers and correct data" do + actual_content = nil + expected_content = "zip-name,date-time zipped folder generated,zip-file-uri\nsome_file_base_name,2025-05-01 00:00:00 +0100,some_file_base_name.zip\nsome_sales_file_base_name,2025-05-01 00:00:00 +0100,some_sales_file_base_name.zip\n" + allow(storage_service).to receive(:write_file).with(expected_master_manifest_filename, any_args) { |_, arg2| actual_content = arg2&.string } + + export_service.export_xml + expect(actual_content).to eq(expected_content) + end + end + + context "and one user archive gets created in user export" do + let(:users_export_service) { instance_double("Exports::UserExportService", export_xml_users: { "some_user_file_base_name" => start_time }) } + + it "generates a master manifest with the correct name" do + expect(storage_service).to receive(:write_file).with(expected_master_manifest_filename, any_args) + export_service.export_xml + end + + it "generates a master manifest with CSV headers and correct data" do + actual_content = nil + expected_content = "zip-name,date-time zipped folder generated,zip-file-uri\nsome_file_base_name,2025-05-01 00:00:00 +0100,some_file_base_name.zip\nsome_sales_file_base_name,2025-05-01 00:00:00 +0100,some_sales_file_base_name.zip\nsome_user_file_base_name,2025-05-01 00:00:00 +0100,some_user_file_base_name.zip\n" + allow(storage_service).to receive(:write_file).with(expected_master_manifest_filename, any_args) { |_, arg2| actual_content = arg2&.string } + + export_service.export_xml + expect(actual_content).to eq(expected_content) + end + end + end + + context "and multiple sales archives get created in sales logs export" do + let(:sales_logs_export_service) { instance_double("Exports::SalesLogExportService", export_xml_sales_logs: { "some_sales_file_base_name" => start_time, "second_sales_file_base_name" => start_time }) } + let(:lettings_logs_export_service) { instance_double("Exports::LettingsLogExportService", export_xml_lettings_logs: { "some_file_base_name" => start_time, "second_file_base_name" => start_time }) } + + context "and no user archives get created in user export" do + it "generates a master manifest with the correct name" do + expect(storage_service).to receive(:write_file).with(expected_master_manifest_filename, any_args) + export_service.export_xml + end + + it "generates a master manifest with CSV headers and correct data" do + actual_content = nil + expected_content = "zip-name,date-time zipped folder generated,zip-file-uri\nsome_file_base_name,2025-05-01 00:00:00 +0100,some_file_base_name.zip\nsecond_file_base_name,2025-05-01 00:00:00 +0100,second_file_base_name.zip\nsome_sales_file_base_name,2025-05-01 00:00:00 +0100,some_sales_file_base_name.zip\nsecond_sales_file_base_name,2025-05-01 00:00:00 +0100,second_sales_file_base_name.zip\n" + allow(storage_service).to receive(:write_file).with(expected_master_manifest_filename, any_args) { |_, arg2| actual_content = arg2&.string } + + export_service.export_xml + expect(actual_content).to eq(expected_content) + end + end + + context "and multiple user archive gets created in user export" do + let(:users_export_service) { instance_double("Exports::UserExportService", export_xml_users: { "some_user_file_base_name" => start_time, "second_user_file_base_name" => start_time }) } + + it "generates a master manifest with the correct name" do + expect(storage_service).to receive(:write_file).with(expected_master_manifest_filename, any_args) + export_service.export_xml + end + + it "generates a master manifest with CSV headers and correct data" do + actual_content = nil + expected_content = "zip-name,date-time zipped folder generated,zip-file-uri\nsome_file_base_name,2025-05-01 00:00:00 +0100,some_file_base_name.zip\nsecond_file_base_name,2025-05-01 00:00:00 +0100,second_file_base_name.zip\nsome_sales_file_base_name,2025-05-01 00:00:00 +0100,some_sales_file_base_name.zip\nsecond_sales_file_base_name,2025-05-01 00:00:00 +0100,second_sales_file_base_name.zip\nsome_user_file_base_name,2025-05-01 00:00:00 +0100,some_user_file_base_name.zip\nsecond_user_file_base_name,2025-05-01 00:00:00 +0100,second_user_file_base_name.zip\n" + allow(storage_service).to receive(:write_file).with(expected_master_manifest_filename, any_args) { |_, arg2| actual_content = arg2&.string } + + export_service.export_xml + expect(actual_content).to eq(expected_content) + end + end + + context "and multiple user and organisation archives gets created in user export" do + let(:users_export_service) { instance_double("Exports::UserExportService", export_xml_users: { "some_user_file_base_name" => start_time, "second_user_file_base_name" => start_time }) } + let(:organisations_export_service) { instance_double("Exports::OrganisationExportService", export_xml_organisations: { "some_organisation_file_base_name" => start_time, "second_organisation_file_base_name" => start_time }) } + + it "generates a master manifest with the correct name" do + expect(storage_service).to receive(:write_file).with(expected_master_manifest_filename, any_args) + export_service.export_xml + end + + it "generates a master manifest with CSV headers and correct data" do + actual_content = nil + expected_content = "zip-name,date-time zipped folder generated,zip-file-uri\nsome_file_base_name,2025-05-01 00:00:00 +0100,some_file_base_name.zip\nsecond_file_base_name,2025-05-01 00:00:00 +0100,second_file_base_name.zip\nsome_sales_file_base_name,2025-05-01 00:00:00 +0100,some_sales_file_base_name.zip\nsecond_sales_file_base_name,2025-05-01 00:00:00 +0100,second_sales_file_base_name.zip\nsome_user_file_base_name,2025-05-01 00:00:00 +0100,some_user_file_base_name.zip\nsecond_user_file_base_name,2025-05-01 00:00:00 +0100,second_user_file_base_name.zip\nsome_organisation_file_base_name,2025-05-01 00:00:00 +0100,some_organisation_file_base_name.zip\nsecond_organisation_file_base_name,2025-05-01 00:00:00 +0100,second_organisation_file_base_name.zip\n" + allow(storage_service).to receive(:write_file).with(expected_master_manifest_filename, any_args) { |_, arg2| actual_content = arg2&.string } + + export_service.export_xml + expect(actual_content).to eq(expected_content) + end + end + end + end + end + + context "when exporting specific sales log collection" do + let(:start_time) { Time.zone.local(2025, 5, 1) } + let(:expected_master_manifest_filename) { "Manifest_2025_05_01_0001.csv" } + let(:lettings_logs_export_service) { instance_double("Exports::LettingsLogExportService", export_xml_lettings_logs: {}) } + + context "and no sales archives get created in sales logs export" do + let(:sales_logs_export_service) { instance_double("Exports::SalesLogExportService", export_xml_sales_logs: {}) } + + context "and user archive gets created in user export" do + let(:users_export_service) { instance_double("Exports::UserExportService", export_xml_users: { "some_user_file_base_name" => start_time }) } + + it "generates a master manifest with the correct name" do + expect(storage_service).to receive(:write_file).with(expected_master_manifest_filename, any_args) + export_service.export_xml(full_update: true, collection: "sales", year: "2022") + end + + it "does not write user data" do + actual_content = nil + expected_content = "zip-name,date-time zipped folder generated,zip-file-uri\n" + allow(storage_service).to receive(:write_file).with(expected_master_manifest_filename, any_args) { |_, arg2| actual_content = arg2&.string } + + export_service.export_xml(full_update: true, collection: "sales", year: "2022") + expect(actual_content).to eq(expected_content) + end + end + end + + context "and sales archive gets created in sales logs export" do + let(:sales_logs_export_service) { instance_double("Exports::SalesLogExportService", export_xml_sales_logs: { "some_sales_file_base_name" => start_time }) } + + context "and user archive gets created in user export" do + let(:users_export_service) { instance_double("Exports::UserExportService", export_xml_users: { "some_user_file_base_name" => start_time }) } + + it "generates a master manifest with the correct name" do + expect(storage_service).to receive(:write_file).with(expected_master_manifest_filename, any_args) + export_service.export_xml(full_update: true, collection: "sales", year: "2023") + end + + it "does not write user data" do + actual_content = nil + expected_content = "zip-name,date-time zipped folder generated,zip-file-uri\nsome_sales_file_base_name,2025-05-01 00:00:00 +0100,some_sales_file_base_name.zip\n" + allow(storage_service).to receive(:write_file).with(expected_master_manifest_filename, any_args) { |_, arg2| actual_content = arg2&.string } + + export_service.export_xml(full_update: true, collection: "sales", year: "2023") + expect(actual_content).to eq(expected_content) + end + end + end + end end