Browse Source

Fixes #5362 - Fix behaviour of array values in CSV export/import.

Co-authored-by: Florian Liebe <fl@zammad.com>


(cherry picked from commit 0b11fbf48b509124c08cee47f27a8851ede17186)

a0ad036a Fixes #5362 - Fix behaviour of array values in CSV export/import.
fd16c58a fix import csv
d676d2c0 remove newline
aebefdcb fix role import test
233de890 fix member import test

Co-authored-by: Rolf Schmidt <rolf.schmidt@zammad.com>
Rolf Schmidt 5 months ago
parent
commit
9147c3be88

+ 11 - 43
app/models/concerns/can_csv_import.rb

@@ -80,26 +80,13 @@ returns
       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 = {
@@ -268,36 +255,17 @@ returns
       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.

+ 0 - 1
spec/fixtures/files/csv_import/organization/simple.csv

@@ -1,4 +1,3 @@
 id;name;members;active
 ;organization-member-import1;customer1-members@example.com
 ;organization-member-import2;customer2-members@example.com;false
-

+ 1 - 1
spec/models/concerns/can_csv_import_organization_examples.rb

@@ -138,7 +138,7 @@ RSpec.shared_examples 'CanCsvImport - Organization specific tests', :aggregate_f
     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

+ 3 - 1
spec/models/concerns/can_csv_import_user_examples.rb

@@ -197,7 +197,9 @@ RSpec.shared_examples 'CanCsvImport - User specific tests', :aggregate_failures
 
     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;user-role-import1@example.com;Customer;\nuser-role-import2;firstname-role-import2;lastname-role-import2;user-role-import2@example.com;Agent\n;;;;Admin" }
+      let(:csv_string) do
+        "login;firstname;lastname;email;roles;\nuser-role-import1;firstname-role-import1;lastname-role-import1;user-role-import1@example.com;Customer;\nuser-role-import2;firstname-role-import2;lastname-role-import2;user-role-import2@example.com;Agent~~~Admin"
+      end
 
       context 'with :try' do
         it 'returns success' do