Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Display errors taking place during import partner process #4707

Merged
merged 10 commits into from
Oct 22, 2024
8 changes: 6 additions & 2 deletions app/controllers/concerns/importable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,12 @@ def import_csv
data = File.read(params[:file].path, encoding: "BOM|UTF-8")
csv = CSV.parse(data, headers: true).reject { |row| row.to_hash.values.any?(&:nil?) }
if csv.count.positive? && csv.first.headers.all? { |header| !header.nil? }
resource_model.import_csv(csv, current_organization.id)
flash[:notice] = "#{resource_model_humanized} were imported successfully!"
errors = resource_model.import_csv(csv, current_organization.id)
if errors.empty?
flash[:notice] = "#{resource_model_humanized} were imported successfully!"
else
flash[:error] = "The following #{resource_model_humanized} did not import successfully:\n#{errors.join("\n")}"
end
else
flash[:error] = "Check headers in file!"
end
Expand Down
3 changes: 2 additions & 1 deletion app/models/concerns/provideable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@ module Provideable
where(organization: organization).order(:business_name)
}

def self.import_csv(csv, organization)
def self.import_csv(csv, organization, errors = [])
jp524 marked this conversation as resolved.
Show resolved Hide resolved
csv.each do |row|
loc = new(row.to_hash)
loc.organization_id = organization

loc.save!
end
errors
end

def self.csv_export_headers
Expand Down
3 changes: 2 additions & 1 deletion app/models/donation_site.rb
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,13 @@ class DonationSite < ApplicationRecord

scope :alphabetized, -> { order(:name) }

def self.import_csv(csv, organization)
def self.import_csv(csv, organization, errors = [])
csv.each do |row|
loc = DonationSite.new(row.to_hash)
loc.organization_id = organization
loc.save!
end
errors
jp524 marked this conversation as resolved.
Show resolved Hide resolved
end

def self.csv_export_headers
Expand Down
6 changes: 5 additions & 1 deletion app/models/partner.rb
Original file line number Diff line number Diff line change
Expand Up @@ -157,15 +157,19 @@ def approvable?
end

# better to extract this outside of the model
def self.import_csv(csv, organization_id)
def self.import_csv(csv, organization_id, errors = [])
jp524 marked this conversation as resolved.
Show resolved Hide resolved
organization = Organization.find(organization_id)

csv.each do |row|
hash_rows = Hash[row.to_hash.map { |k, v| [k.downcase, v] }]

svc = PartnerCreateService.new(organization: organization, partner_attrs: hash_rows)
svc.call
if svc.errors.present?
errors << "#{svc.partner.name}: #{svc.partner.errors.full_messages.to_sentence}"
end
end
errors
end

def self.csv_export_headers
Expand Down
3 changes: 2 additions & 1 deletion app/models/storage_location.rb
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,13 @@ def to_csv
end

# NOTE: We should generalize this elsewhere -- Importable concern?
def self.import_csv(csv, organization)
def self.import_csv(csv, organization, errors = [])
csv.each do |row|
loc = StorageLocation.new(row.to_hash)
loc.organization_id = organization
loc.save!
end
errors
end

# NOTE: We should generalize this elsewhere -- Importable concern?
Expand Down
32 changes: 16 additions & 16 deletions app/services/partner_create_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,27 +11,27 @@ def initialize(organization:, partner_attrs:)
def call
@partner = organization.partners.build(partner_attrs)

unless @partner.valid?
if @partner.valid?
ActiveRecord::Base.transaction do
@partner.save!

Partners::Profile.create!({
partner_id: @partner.id,
name: @partner.name,
enable_child_based_requests: organization.enable_child_based_requests,
enable_individual_requests: organization.enable_individual_requests,
enable_quantity_based_requests: organization.enable_quantity_based_requests
})
rescue StandardError => e
errors.add(:base, e.message)
raise ActiveRecord::Rollback
end
else
@partner.errors.each do |error|
errors.add(error.attribute, error.message)
end
end

ActiveRecord::Base.transaction do
@partner.save!

Partners::Profile.create!({
partner_id: @partner.id,
name: @partner.name,
enable_child_based_requests: organization.enable_child_based_requests,
enable_individual_requests: organization.enable_individual_requests,
enable_quantity_based_requests: organization.enable_quantity_based_requests
})
rescue StandardError => e
errors.add(:base, e.message)
raise ActiveRecord::Rollback
end

self
end

Expand Down
4 changes: 4 additions & 0 deletions spec/fixtures/files/partners_with_invalid_email.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
name,email
Partner 1,[email protected]
Partner 2,this is not an email address
Partner 3,[email protected]
20 changes: 20 additions & 0 deletions spec/requests/partners_requests_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,26 @@
expect(response).to have_error "Check headers in file!"
end
end

context "csv file with invalid email address" do
let(:file) { fixture_file_upload("partners_with_invalid_email.csv", "text/csv") }
subject { post import_csv_partners_path, params: { file: file } }

it "invokes .import_csv" do
expect(model_class).to respond_to(:import_csv).with(2).arguments
end

it "redirects to :index" do
subject
expect(response).to be_redirect
end

it "presents a flash notice message displaying the import errors" do
subject
expect(response).to have_error(/The following #{model_class.name.underscore.humanize.pluralize} did not import successfully:/)
expect(response).to have_error(/Partner 2: Email is invalid/)
end
end
end

describe "POST #create" do
Expand Down