Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions app/controllers/dynamic_forms/submissions_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,19 @@
module DynamicForms
class SubmissionsController < DynamicForms::ApplicationController
before_action :load_custom_form
before_action :load_submission, only: %w[destroy]
before_action :load_submission, only: %i[destroy]
before_action :load_submissions, only: %i[index export]

def index
@submissions = @custom_form.submissions
.order('created_at DESC')
.page(params[:page])
respond_to do |format|
format.html
format.csv {
send_data(
SubmissionExporter.for(@custom_form.submissions.order('created_at'), 'csv'),
filename: "submissions-#{Date.today}.csv"
)
}
end
end

def destroy
Expand All @@ -20,6 +27,7 @@ def destroy
redirect_to custom_form_submissions_path(@custom_form)
end


private

def load_custom_form
Expand All @@ -29,6 +37,12 @@ def load_custom_form
redirect_to custom_forms_path
end

def load_submissions
@submissions = @custom_form.submissions
.order('created_at DESC')
.page(params[:page])
end

def load_submission
@submission = @custom_form.submissions.find(params[:id])
rescue
Expand Down
67 changes: 67 additions & 0 deletions app/services/dynamic_forms/submission_exporter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
require 'csv'

module DynamicForms
class SubmissionExporter
FORMAT_DATE = '%B %m, %Y, %H:%M'.freeze

def self.for(submissions, format_type)
new(submissions, format_type).export
end

def initialize(submissions, format_type)
raise TypeError, "Expected an string, got #{format_type.class.name}" unless format_type.is_a?(String)
raise ArgumentError, 'Expected submissions' if submissions.nil?

@submissions = submissions
@format_type = format_type
end

def export
case @format_type
when 'csv'
to_csv
when 'xls'
to_xls
else
raise ArgumentError, 'This format is not available'
end
end

private

def to_csv
CSV.generate(headers: true) do |csv|
header = ['Created at'] + build_header
csv << header

@submissions.each do |submission|
csv << [].tap do |row|
row[0] = submission.created_at.strftime(FORMAT_DATE)
submission.fields.each do |key, value|
column_name = key.capitalize
column_index = header.find_index(column_name)

row[column_index] = value
end
end
end

@submissions.map do |submission|
header.each do |column|
column_name = column.downcase

end
end
end
end

def to_xls
end

def build_header
Submission
.select('json_object_keys(fields) as field_keys')
.distinct.map{ |s| s.field_keys.capitalize }
end
end
end
6 changes: 6 additions & 0 deletions app/views/dynamic_forms/submissions/_export_as.html.haml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
.dropdown
%button#dropdownMenuButton.btn.btn-link.dropdown-toggle{"aria-expanded" => "false", "aria-haspopup" => "true", "data-toggle" => "dropdown", :type => "button"}
Export as
.dropdown-menu{"aria-labelledby": "dropdownMenuButton"}
= link_to 'CSV', custom_form_submissions_path(@custom_form, format: 'csv'), class: 'dropdown-item'
= link_to 'XLS', custom_form_submissions_path(@custom_form, format: 'csv'), class: 'dropdown-item'
4 changes: 3 additions & 1 deletion app/views/dynamic_forms/submissions/index.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@
.col-12
.card.my-5
.card-header
%h2=@custom_form.name.titleize
.d-flex.justify-content-between
%h2=@custom_form.name.titleize
= render 'export_as'
.card-body
.row
.col-1.p-2.font-weight-bold
Expand Down
2 changes: 1 addition & 1 deletion spec/dummy/config/database.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ development:

test:
<<: *default
database: dynamic_forms
database: dynamic_forms_test

production:
<<: *default
58 changes: 58 additions & 0 deletions spec/services/dynamic_forms/submission_exporter_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
require 'rails_helper'

describe DynamicForms::SubmissionExporter do
let!(:submissions) { create_list(:submission, 5, created_at: '2019-10-08 19:39:06 UTC') }
let!(:with_different_field) {
create_list(
:submission,
5,
fields: { age: '12', phone: '1231432', gender: 'F' },
created_at: '2019-10-08 19:39:06 UTC'
)
}

let(:all_submissions) { DynamicForms::Submission.all }

context 'when submissions are not sent correclty' do
subject { DynamicForms::SubmissionExporter.for(nil, 'csv') }
it 'returns an ArgumentError' do
expect { subject }.to raise_error(ArgumentError)
end
end

context 'when the format type is not sent correctly' do
context 'when the format type is not string' do
subject { DynamicForms::SubmissionExporter.for(all_submissions, nil) }

it 'returns a TypeError' do
expect { subject }.to raise_error(TypeError)
end
end

context 'when the format type is not available' do
subject { DynamicForms::SubmissionExporter.for(all_submissions, 'pdf') }

it 'returns a ArgumentError' do
expect { subject }.to raise_error(ArgumentError)
end
end
end

context '#to_csv' do
subject { DynamicForms::SubmissionExporter.for(all_submissions, 'csv') }
let!(:rows) { subject.split("\n") }

it 'returns a csv content with 11 lines' do
expect(rows.size).to eq(11)
end

it 'includes the header' do
expect(rows.first).to eq('Created at,Gender,_subject,Phone,Age,Email,Name')
end

it 'includes data with fields correctly' do
expect(rows.slice(2)).to eq("\"October 10, 2019, 19:39\",,Test email,,,[email protected],John")
expect(rows.slice(6)).to eq("\"October 10, 2019, 19:39\",F,,1231432,12")
end
end
end