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

bulk add opportunities #341

Merged
merged 1 commit into from
Nov 27, 2015
Merged
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
13 changes: 10 additions & 3 deletions app/assets/stylesheets/opportunities.scss
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
// Place all the styles related to the Opportunities controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
.opportunities > table{
width: 60%;
}

.opportunities {
table {
width: 60%;
}

&.bulk-add table {
width: 100%;
}
}
46 changes: 39 additions & 7 deletions app/controllers/opportunities_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,44 @@ def new
@opportunity = Opportunity.new
end

@@permitted_params = [:name, :address, :description, :registration_url, :location_name,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this the right way to do this, @dmtroyer? I'm trying to expose the permitted_params to the view so we can loop over them programmatically.

:registration_deadline, :program_type, :logo_url, :starts_at,
:ends_at, :online_address, :zipcode, :city, :state, :is_online,
:hide_reason, :hide, :contact_name, :contact_email, :contact_phone,
:registration_url, :price_level, :min_age, :max_age, :extra_data,
:topic_id, :organizer_id, :resource_sub_type_id]

# GET,POST /opportunities/bulk-add
def bulk_add
@permitted_params = @@permitted_params
@opportunities = []
@nbad = 0
@nerrors = 0

if request.method == 'POST'
Opportunity.transaction do
CSV.parse(params[:csv].read, headers: true) do |row|
topic = Topic.find_by_name(row.delete('topic'))
sub_type = ResourceSubType.find_by_name(row.delete('resource_sub_type'))

row['organizer_id'] = params[:organizer_id]
row['topic_id'] = unless topic.nil? then topic.id else nil end
row['resource_sub_type_id'] = unless sub_type.nil? then sub_type.id else nil end

opportunity = Opportunity.create(row.to_h)
@opportunities.push(opportunity)
if opportunity.errors.count > 0
@nbad += 1
@nerrors += opportunity.errors.count
end
end
end
end

@topic_names = Topic.pluck(:name)
@sub_type_names = ResourceSubType.pluck(:name)
end

# GET /opportunities/1/edit
def edit
authorize @opportunity
Expand Down Expand Up @@ -88,12 +126,6 @@ def set_organizers

# Never trust parameters from the scary internet, only allow the white list through.
def opportunity_params
permitted_params = [:name, :address, :description, :registration_url, :location_name,
:registration_deadline, :program_type, :logo_url, :starts_at,
:ends_at, :online_address, :zipcode, :city, :state, :is_online,
:hide_reason, :hide, :contact_name, :contact_email, :contact_phone,
:registration_url, :price_level, :min_age, :max_age, :extra_data,
:organizer_id, :resource_sub_type_id]
params.require(:opportunity).permit(permitted_params)
params.require(:opportunity).permit(@@permitted_params)
end
end
19 changes: 19 additions & 0 deletions app/models/opportunity.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,25 @@ class Opportunity < ActiveRecord::Base

validates :resource_sub_type, presence: true

validates :name, presence: true, allow_blank: false, uniqueness: { scope: :organizer }
validates :description, presence: true, allow_blank: false
validates :registration_url, presence: true, allow_blank: false
validates :program_type, presence: true, allow_blank: false
validates :logo_url, presence: true, allow_blank: false
validates :is_online, presence: true
validates :contact_name, presence: true, allow_blank: false
validates :contact_email, presence: true, allow_blank: false
validates :contact_phone, presence: true, allow_blank: false
validates :organizer, presence: true, allow_blank: false

validates :price_level, presence: true, :numericality => { :greater_than_or_equal_to => 0 }
validates :min_age, presence: true, :numericality => { :greater_than_or_equal_to => 0 }
validates :max_age, presence: true, :numericality => { :greater_than_or_equal_to => 0 }

validates :registration_deadline, presence: true
validates :starts_at, presence: true
validates :ends_at, presence: true

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dat validation 👍

def active_model_serializer
OpportunitySerializer
end
Expand Down
3 changes: 2 additions & 1 deletion app/views/dashboard/opportunities.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

<div class="opportunities">
<%= link_to '<button>Add New Opportunity</button>'.html_safe, new_opportunity_path %>
<%= link_to '<button>Bulk Add New Opportunities</button>'.html_safe, bulk_add_opportunities_path %>

<br />
<br />
Expand All @@ -23,4 +24,4 @@
<% end %>
</tbody>
</table>
</div>
</div>
89 changes: 89 additions & 0 deletions app/views/opportunities/bulk_add.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
<h1 class="page">Dashboard > Bulk Add Opportunities</h1>

<div class="opportunities bulk-add">
<%= form_tag({action: :bulk_add}, multipart: true) do %>

<h2>Step 1: Set the Organizer</h2>

<%= select_tag(:organizer_id, options_for_select(current_user.organizers.map {|o| [o.name, o.id]})) %>


<h2>Step 2: Download the CSV Template</h2>

<p><a href="/opportunities.csv">Download the CSV template</a> to see what
fields are required and example values showing the expected format. Edit it
in Excel to enter your own data. Here are some notes on specific fields:</p>

<ul>
<li><b>program_type</b>&mdash;pick any value for this that makes sense for you</li>
<li><b>is_online</b>&mdash;"true" or "false"</li>
<li><b>topic</b>&mdash;must be: "<%= @topic_names.join('", "')%>"</li>
<li><b>resource_sub_type</b>&mdash;must be: "<%= @sub_type_names.join('", "')%>"</li>
</ul>


<h2>Step 3: Upload Your CSV</h2>

<%= file_field_tag 'csv' %>
<%= submit_tag('Upload') %>
<% end %>


<style>
td.good { background: #CCFFCC; }
td.bad { background: #FFCCCC; }
h2.disabled { color: #CCC; }
</style>

<% if not @opportunities.present? %>
<h2 class="disabled">Step 4: Review Results</h2>
<% else %>
<h2>Step 4: Review Results</h2>

<% if @nbad > 0 %>
<h3>We found <%= pluralize(@nerrors, "error") %> in <%= pluralize(@nbad, "record") %>.</h3>
<% end %>

<table class="pure-table pure-table-bordered">
<thead>
<tr>
<th>actions</th>
<% @permitted_params.each do |param| %>
<th><%= param %></th>
<% end %>
</tr>
</thead>

<tbody>
<% @opportunities.each do |opportunity| %>
<tr>
<% if opportunity.valid? %>
<td class="good">
<%= link_to "<button>show</button>".html_safe, opportunity %>
<%= link_to "<button>edit</button>".html_safe, edit_opportunity_path(opportunity) %>
<% else %>
<td class="bad">
&#10008;
<% end %>
</td>
<% @permitted_params.each do |param| %>
<% if opportunity.errors[param].present? %>
<td class="bad">
<%= opportunity.send(param) %>
<ul>
<% opportunity.errors[param].each do |error| %>
<li><%= error %></li>
<% end %>
</ul>
<% else %>
<td class="good">
<%= opportunity.send(param) %>
<% end %>
</td>
<% end %>
</tr>
<% end %>
</tbody>
</table>
<% end %>
</div>
1 change: 1 addition & 0 deletions config/application.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
require File.expand_path('../boot', __FILE__)

require 'rails/all'
require 'csv'

# Require the gems listed in Gemfile, including any gems
# you've limited to :test, :development, or :production.
Expand Down
12 changes: 8 additions & 4 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,23 @@
get 'dashboard/home'

scope '/dashboard' do

root :to => 'application#index'

devise_for :users, :skip => [ :registrations ]
resources :registrations, only: [:create] do
collection do
collection do
get 'organizer_registration'
end
end
resources :topics
resources :organizers
resources :venues
resources :opportunities
resources :opportunities do
collection do
match 'bulk-add', action: :bulk_add, via: [:get, :post]
end
end
resources :opportunity_instances
end

Expand Down
2 changes: 2 additions & 0 deletions public/opportunities.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
name,description,registration_deadline,starts_at,ends_at,registration_url,program_type,logo_url,is_online,contact_name,contact_email,contact_phone,price_level,min_age,max_age,topic,resource_sub_type
Marbles,It's marble time!,2020-10-10,2020-10-10,2020-10-10,http://example.com/,Workshop,http://example.com/logo,true,Alice W. Underland,[email protected],+1-555-867-5309,10,0,1000,Making,Event