Browse Source

Start of Zip generation

pull/587/head
Stéphane Meny 3 years ago
parent
commit
3659b7bae6
No known key found for this signature in database
GPG Key ID: 9D0AFEA988527923
  1. 59
      app/services/exports/case_log_export_service.rb
  2. 45
      spec/services/exports/case_log_export_service_spec.rb

59
app/services/exports/case_log_export_service.rb

@ -1,15 +1,29 @@
module Exports module Exports
class CaseLogExportService class CaseLogExportService
QUARTERS = {
0 => "jan_mar",
1 => "apr_jun",
2 => "jul_sep",
3 => "oct_dec"
}.freeze
LOG_ID_OFFSET = 300_000_000_000
def initialize(storage_service, logger = Rails.logger) def initialize(storage_service, logger = Rails.logger)
@storage_service = storage_service @storage_service = storage_service
@logger = logger @logger = logger
end end
def export_case_logs def export_case_logs
# Case log data is already ordered by startdate
case_logs = retrieve_case_logs case_logs = retrieve_case_logs
export = save_export_run daily_run_number = get_next_run_number
write_master_manifest(export) write_master_manifest(daily_run_number)
write_export_data(case_logs) write_export_data(case_logs)
export = LogsExport.new(daily_run_number:)
export.save!
export
end end
def is_omitted_field?(field_name) def is_omitted_field?(field_name)
@ -18,44 +32,55 @@ module Exports
field_name.starts_with?("details_known_") || pattern_age.match(field_name) || omitted_attrs.include?(field_name) ? true : false field_name.starts_with?("details_known_") || pattern_age.match(field_name) || omitted_attrs.include?(field_name) ? true : false
end end
LOG_ID_OFFSET = 300_000_000_000
private private
def save_export_run def get_next_run_number
today = Time.zone.today today = Time.zone.today
last_daily_run_number = LogsExport.where(created_at: today.beginning_of_day..today.end_of_day).maximum(:daily_run_number) last_daily_run_number = LogsExport.where(created_at: today.beginning_of_day..today.end_of_day).maximum(:daily_run_number)
export = LogsExport.new
if last_daily_run_number.nil? if last_daily_run_number.nil?
export.daily_run_number = 1 1
else else
export.daily_run_number = last_daily_run_number + 1 last_daily_run_number + 1
end end
export.save!
export
end end
def write_master_manifest(export) def write_master_manifest(daily_run_number)
today = Time.zone.today today = Time.zone.today
increment_number = export.daily_run_number.to_s.rjust(4, "0") increment_number = daily_run_number.to_s.rjust(4, "0")
month = today.month.to_s.rjust(2, "0") month = today.month.to_s.rjust(2, "0")
day = today.day.to_s.rjust(2, "0") day = today.day.to_s.rjust(2, "0")
file_path = "Manifest_#{today.year}-#{month}-#{day}_#{increment_number}.csv" file_path = "Manifest_#{today.year}_#{month}_#{day}_#{increment_number}.csv"
string_io = build_manifest_csv_io string_io = build_manifest_csv_io
@storage_service.write_file(file_path, string_io) @storage_service.write_file(file_path, string_io)
end end
def get_zip_naming(case_log, base_number, increment)
collection_start = case_log.collection_start_year
month = case_log.startdate.month
quarter = QUARTERS[(month - 1) / 3]
base_number_str = "f#{base_number.to_s.rjust(4, '0')}"
increment_str = "inc#{increment.to_s.rjust(3, '0')}"
"core_#{collection_start}_#{collection_start + 1}_#{quarter}_#{base_number_str}_#{increment_str}.zip"
end
def write_export_data(case_logs) def write_export_data(case_logs)
zip_filenames = []
case_logs.each do |case_log|
zip_filename= get_zip_naming(case_log, 1, 1)
unless zip_filenames.include?(zip_filename)
zip_io = Zip::File.open_buffer(StringIO.new)
zip_io.add("my_file", Tempfile.new)
@storage_service.write_file(zip_filename, zip_io.write_buffer)
end
end
string_io = build_export_xml_io(case_logs) string_io = build_export_xml_io(case_logs)
file_path = "#{get_folder_name}/#{get_file_name}.xml" file_path = "#{get_folder_name}/#{get_file_name}.xml"
@storage_service.write_file(file_path, string_io) @storage_service.write_file(file_path, string_io)
end end
def retrieve_case_logs def retrieve_case_logs
# All logs from previous (successful) start time to current start time (not current) [ignore status] CaseLog.all
params = { from: Time.current.beginning_of_day, to: Time.current, status: CaseLog.statuses[:completed] }
CaseLog.where("updated_at >= :from and updated_at <= :to and status = :status", params)
end end
def build_manifest_csv_io def build_manifest_csv_io

45
spec/services/exports/case_log_export_service_spec.rb

@ -2,14 +2,9 @@ require "rails_helper"
RSpec.describe Exports::CaseLogExportService do RSpec.describe Exports::CaseLogExportService do
let(:storage_service) { instance_double(StorageService) } let(:storage_service) { instance_double(StorageService) }
let(:export_filepath) { "spec/fixtures/exports/case_logs.xml" } let(:export_filepath) { "spec/fixtures/exports/case_logs.xml" }
let(:export_file) { File.open(export_filepath, "r:UTF-8") } let(:export_file) { File.open(export_filepath, "r:UTF-8") }
let(:expected_master_manifest_filename) { "Manifest_2022_05_01_0001.csv" }
let(:expected_data_filename) { "core_2022_02_08/dat_core_2022_02_08_0001.xml" }
let(:expected_master_manifest_filename) { "Manifest_2022_02_08_0001.csv" }
let(:expected_master_manifest_filename2) { "Manifest_2022_02_08_0002.csv" }
let(:case_log) { FactoryBot.create(:case_log, :completed) } let(:case_log) { FactoryBot.create(:case_log, :completed) }
def replace_entity_ids(export_template) def replace_entity_ids(export_template)
@ -22,10 +17,10 @@ RSpec.describe Exports::CaseLogExportService do
context "when exporting daily case logs" do context "when exporting daily case logs" do
subject(:export_service) { described_class.new(storage_service) } subject(:export_service) { described_class.new(storage_service) }
let(:case_log) { FactoryBot.create(:case_log, :completed) } let!(:case_log) { FactoryBot.create(:case_log, :completed) }
before do before do
Timecop.freeze(case_log.updated_at) Timecop.freeze(2022, 5, 1)
allow(storage_service).to receive(:write_file) allow(storage_service).to receive(:write_file)
end end
@ -45,13 +40,21 @@ RSpec.describe Exports::CaseLogExportService do
end end
end end
context "and case logs are available for export" do context "and one case log is available for export" do
before do let(:expected_zip_filename) { "core_2021_2022_jan_mar_f0001_inc001.zip" }
case_log let(:expected_data_filename) { "core_2022_02_08/dat_core_2022_02_08_0001.xml" }
it "generates a ZIP export file with the expected filename" do
expect(storage_service).to receive(:write_file).with(expected_zip_filename, any_args)
export_service.export_case_logs
end end
it "generates an XML export file with the expected filename" do it "generates an XML export file with the expected filename within the ZIP file" do
expect(storage_service).to receive(:write_file).with(expected_data_filename, any_args) allow(storage_service).to receive(:write_file).with(expected_zip_filename, any_args) do |_, content|
pp Zip::File.open_buffer(content).entries
expect(content).to eq("Manifest_2022_05_01_0001.csv")
end
export_service.export_case_logs export_service.export_case_logs
end end
@ -65,13 +68,27 @@ RSpec.describe Exports::CaseLogExportService do
end end
end end
context "and multiple case logs are available for export" do
let!(:case_log_2) { FactoryBot.create(:case_log, startdate: Time.zone.local(2022, 4, 1)) }
context "when case logs are across multiple quarters" do
it "generates multiple ZIP export files with the expected filenames" do
expect(storage_service).to receive(:write_file).with("core_2021_2022_jan_mar_f0001_inc001.zip", any_args)
expect(storage_service).to receive(:write_file).with("core_2022_2023_apr_jun_f0001_inc001.zip", any_args)
export_service.export_case_logs
end
end
end
context "and a previous export has run the same day" do context "and a previous export has run the same day" do
let(:expected_master_manifest_rerun) { "Manifest_2022_05_01_0002.csv" }
before do before do
export_service.export_case_logs export_service.export_case_logs
end end
it "increments the master manifest number by 1" do it "increments the master manifest number by 1" do
expect(storage_service).to receive(:write_file).with(expected_master_manifest_filename2, any_args) expect(storage_service).to receive(:write_file).with(expected_master_manifest_rerun, any_args)
export_service.export_case_logs export_service.export_case_logs
end end
end end

Loading…
Cancel
Save