Skip to content

Commit

Permalink
Fixes zammad#5362 - Fix behaviour of array values in CSV export/import.
Browse files Browse the repository at this point in the history
Co-authored-by: Florian Liebe <[email protected]>
  • Loading branch information
rolfschmidt and fliebe92 committed Oct 9, 2024
1 parent 9d15959 commit 0b11fbf
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 46 deletions.
54 changes: 11 additions & 43 deletions app/models/concerns/can_csv_import.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,26 +80,13 @@ def csv_import(data)
end

# get payload based on csv
payload = []
rows.each do |row|
if row.first(2).any?(&:present?)
payload.push(
header.zip(row).to_h
.compact.transform_values(&:strip)
.except(nil).transform_keys(&:to_sym)
.except(*csv_attributes_ignored)
.merge(data[:fixed_params] || {})
)
else
header.zip(row).to_h
payload = rows.map do |row|
header.zip(row).to_h
.compact.transform_values(&:strip)
.except(nil).except('').transform_keys(&:to_sym)
.each do |col, val|
next if val.blank?

payload.last[col] = [*payload.last[col], val]
end
end
.transform_values { |value| (value.include?('~~~') ? value.split('~~~') : value) }
.except(nil).transform_keys(&:to_sym)
.except(*csv_attributes_ignored)
.merge(data[:fixed_params] || {})
end

stats = {
Expand Down Expand Up @@ -268,36 +255,17 @@ def csv_example(params = {})
rows = []
records_attributes_with_association_names.each do |record|
row = []
rows_to_add = []
position = -1
header.each do |key|
position += 1
if record[key].instance_of?(ActiveSupport::TimeWithZone)
row.push record[key].iso8601
next
elsif record[key].instance_of?(Array)
row.push record[key].join('~~~')
else
row.push record[key]
end
if record[key].instance_of?(Array)
entry_count = -2
record[key].each do |entry|
entry_count += 1
next if entry_count == -1

if !rows_to_add[entry_count]
rows_to_add[entry_count] = Array.new(header.count + 1) { '' }
end
rows_to_add[entry_count][position] = entry
end
record[key] = record[key][0]
end
row.push record[key]
end
rows.push row
next if rows_to_add.count.zero?

rows_to_add.each do |item|
rows.push item
end
rows_to_add = []
rows << row
end

require 'csv' # Only load it when it's really needed to save memory.
Expand Down
1 change: 0 additions & 1 deletion spec/fixtures/files/csv_import/organization/simple.csv
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
id;name;members;active
;organization-member-import1;[email protected]
;organization-member-import2;[email protected];false

Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@
context 'with valid import data including members' do
let(:customer1) { create(:customer) }
let(:customer2) { create(:customer) }
let(:csv_string) { "id;name;members;\n;organization-member-import1;\n;organization-member-import2;#{customer1.email}\n;;#{customer2.email}" }
let(:csv_string) { "id;name;members;\n;organization-member-import1;\n;organization-member-import2;#{customer1.email}~~~#{customer2.email}" }

context 'with :try' do
it 'returns success' do
Expand Down
4 changes: 3 additions & 1 deletion spec/models/concerns/can_csv_import_user_examples.rb
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,9 @@

context 'with roles and fixed params' do
let(:result) { User.csv_import(**params, fixed_params: { note: 'some note' }) }
let(:csv_string) { "login;firstname;lastname;email;roles;\nuser-role-import1;firstname-role-import1;lastname-role-import1;[email protected];Customer;\nuser-role-import2;firstname-role-import2;lastname-role-import2;[email protected];Agent\n;;;;Admin" }
let(:csv_string) do
"login;firstname;lastname;email;roles;\nuser-role-import1;firstname-role-import1;lastname-role-import1;[email protected];Customer;\nuser-role-import2;firstname-role-import2;lastname-role-import2;[email protected];Agent~~~Admin"
end

context 'with :try' do
it 'returns success' do
Expand Down

0 comments on commit 0b11fbf

Please sign in to comment.