diff --git a/app/assets/javascripts/components/upload_csv_box.js.jsx b/app/assets/javascripts/components/upload_csv_box.js.jsx
index d672a1508..2b5edc90f 100644
--- a/app/assets/javascripts/components/upload_csv_box.js.jsx
+++ b/app/assets/javascripts/components/upload_csv_box.js.jsx
@@ -92,17 +92,17 @@ var UploadCsvBox = React.createClass({
const tooltipText = notFoundUuids.slice(0, 5).map((batch_number) =>
{batch_number}
);
const rowContent = errorMessage ?
-
- {uploadedSamplesCount} {samplesText}
- {batchesNotFound > 0 && (
-
- {" ("}{batchesNotFound} {batchesText} not found{")"}
-
- )}
-
:
{errorMessage}
-
;
+ :
+
+ {uploadedSamplesCount} {samplesText}
+ {batchesNotFound > 0 && (
+
+ {" ("}{batchesNotFound} {batchesText} not found{")"}
+
+ )}
+
;
return (
diff --git a/app/controllers/boxes_controller.rb b/app/controllers/boxes_controller.rb
index 63c268f87..c14b32053 100644
--- a/app/controllers/boxes_controller.rb
+++ b/app/controllers/boxes_controller.rb
@@ -57,19 +57,23 @@ def validate
# TODO: should be handled by BoxForm (& duplicates BoxForm#parse_csv)
CSV.open(params[:csv_box].path, headers: true) do |csv|
- while csv.headers == true
- csv.readline
- end
+ unique_rows = Set.new
+ csv.each do |row|
- unless csv.headers == ["Batch", "Concentration", "Distractor", "Instructions"]
- @error_message = "Invalid columns"
- return # rubocop:disable Lint/NonLocalExitFromIterator
- end
+ unless csv.headers == ["Batch", "Concentration", "Distractor", "Instructions", "Replicates"]
+ @error_message = "Invalid columns"
+ return # rubocop:disable Lint/NonLocalExitFromIterator
+ end
+
+ if unique_rows.include?([row["Batch"], row["Concentration"], row["Distractor"], row["Instructions"]])
+ @error_message = "Batch, Concentration, Distractor, Instructions must be unique"
+ return # rubocop:disable Lint/NonLocalExitFromIterator
+ end
+ unique_rows << [row["Batch"], row["Concentration"], row["Distractor"], row["Instructions"]]
- csv.each do |row|
if batch_number = row["Batch"].presence&.strip
batch_numbers << batch_number
- @samples_count += 1
+ @samples_count += row["Replicates"].to_i
end
end
end
diff --git a/app/models/box_form.rb b/app/models/box_form.rb
index 5ece9b0ff..be295e984 100644
--- a/app/models/box_form.rb
+++ b/app/models/box_form.rb
@@ -217,7 +217,7 @@ def parse_csv(path)
instruction: row["Instructions"],
concentrations: {
"0" => {
- replicate: 1,
+ replicate: row["Replicates"].to_i,
concentration: Integer(Float(row["Concentration"]&.strip)),
},
},
diff --git a/public/templates/upload_box.csv b/public/templates/upload_box.csv
index d473086de..de884b586 100644
--- a/public/templates/upload_box.csv
+++ b/public/templates/upload_box.csv
@@ -1,9 +1,5 @@
-Batch,Concentration,Distractor,Instructions
-batch1,100,no,Add 175 ml of media
-batch1,100,no,Add 175 ml of media
-batch1,1000,no,Add 175 ml of media
-batch1,1000,no,Add 175 ml of media
-batch2,2,yes,Add 250 ml of media
-batch2,2,yes,Add 250 ml of media
-batch2,200,yes,Add 100 ml of media
-batch2,200,yes,Add 100 ml of media
+Batch,Concentration,Distractor,Instructions,Replicates
+borrar,100,no,Add 175 ml of media,2
+borrar,1000,no,Add 175 ml of media,2
+Blank,2,yes,Add 250 ml of media,4
+Blank,200,yes,Add 100 ml of media,4
diff --git a/spec/controllers/boxes_controller_spec.rb b/spec/controllers/boxes_controller_spec.rb
index 6c54f9037..1ee427047 100644
--- a/spec/controllers/boxes_controller_spec.rb
+++ b/spec/controllers/boxes_controller_spec.rb
@@ -266,7 +266,7 @@
end
it "validates CSV headers" do
- csv_file = fixture_file_upload(Rails.root.join("spec/fixtures/csvs/samples_results_1.csv"), "text/csv")
+ csv_file = fixture_file_upload(Rails.root.join("spec/fixtures/csvs/csv_box_no_headers.csv"), "text/csv")
expect do
post :validate, params: { csv_box: csv_file }, format: "json"
@@ -292,7 +292,7 @@
expect(JSON.parse(response.body)).to eq({
"found_batches" => ["DISTRACTOR"],
"not_found_batches" => [],
- "samples_count" => 3,
+ "samples_count" => 4,
})
end
@@ -307,7 +307,7 @@
expect(JSON.parse(response.body)).to eq({
"found_batches" => ["DISTRACTOR"],
"not_found_batches" => ["VIRUS"],
- "samples_count" => 5,
+ "samples_count" => 6,
})
end
end
diff --git a/spec/fixtures/csvs/csv_box_1.csv b/spec/fixtures/csvs/csv_box_1.csv
index daedf6626..09342d1af 100644
--- a/spec/fixtures/csvs/csv_box_1.csv
+++ b/spec/fixtures/csvs/csv_box_1.csv
@@ -1,5 +1,3 @@
-Batch,Concentration,Distractor,Instructions
-DISTRACTOR,10,no,Add 10ml
-DISTRACTOR,10,no,Add 10ml
-DISTRACTOR,20,no,Add 10ml
-DISTRACTOR,20,no,Add 10ml
+Batch,Concentration,Distractor,Instructions,Replicates
+DISTRACTOR,10,no,Add 10ml,2
+DISTRACTOR,20,no,Add 10ml,2
diff --git a/spec/fixtures/csvs/csv_box_2.csv b/spec/fixtures/csvs/csv_box_2.csv
index 8084b0a3e..6a6522d5b 100644
--- a/spec/fixtures/csvs/csv_box_2.csv
+++ b/spec/fixtures/csvs/csv_box_2.csv
@@ -1,7 +1,4 @@
-Batch,Concentration,Distractor,Instructions
-VIRUS,10,no,Add 10ml
-VIRUS,10,no,Add 10ml
-DISTRACTOR,10,yes,Add 10ml
-DISTRACTOR,10,yes,Add 10ml
-DISTRACTOR,20,yes,Add 10ml
-DISTRACTOR,20,yes,Add 10ml
+Batch,Concentration,Distractor,Instructions,Replicates
+VIRUS,10,no,Add 10ml,2
+DISTRACTOR,10,yes,Add 10ml,2
+DISTRACTOR,20,yes,Add 10ml,2
diff --git a/spec/fixtures/csvs/csv_box_no_headers.csv b/spec/fixtures/csvs/csv_box_no_headers.csv
new file mode 100644
index 000000000..32198940b
--- /dev/null
+++ b/spec/fixtures/csvs/csv_box_no_headers.csv
@@ -0,0 +1,3 @@
+VIRUS,10,no,Add 10ml,2
+DISTRACTOR,10,yes,Add 10ml,2
+DISTRACTOR,20,yes,Add 10ml,2