Skip to content
Open
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
10 changes: 5 additions & 5 deletions app/controllers/product_drive_participants_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@
class ProductDriveParticipantsController < ApplicationController
include Importable

# TODO: Should there be a :destroy action for this?

def index
@product_drive_participants = current_organization.product_drive_participants.includes(:donations).with_volumes.order(:business_name)
@products = View::ProductDriveParticipants.new(params: params, organization: current_organization)

respond_to do |format|
format.html
format.csv { send_data ProductDriveParticipant.generate_csv(@product_drive_participants), filename: "ProductDriveParticipants-#{Time.zone.today}.csv" }
format.csv { send_data ProductDriveParticipant.generate_csv(@products.participants), filename: "ProductDriveParticipants-#{Time.zone.today}.csv" }
end
end

Expand Down Expand Up @@ -65,6 +63,8 @@ def product_drive_participant_params

helper_method \
def filter_params
{}
return {} unless params.key?(:filters)

params.require(:filters).permit(:by_business_name, :by_contact_name)
end
end
5 changes: 4 additions & 1 deletion app/models/product_drive_participant.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,9 @@

class ProductDriveParticipant < ApplicationRecord
has_paper_trail
include Provideable
include Filterable
include Geocodable
include Provideable

has_many :donations, inverse_of: :product_drive_participant, dependent: :destroy

Expand All @@ -30,6 +31,8 @@ class ProductDriveParticipant < ApplicationRecord
validates :comment, length: { maximum: 500 }

scope :alphabetized, -> { order(:contact_name) }
scope :by_business_name, ->(business_name) { where("business_name ILIKE ?", "%#{business_name}%") }
scope :by_contact_name, ->(contact_name) { where("contact_name ILIKE ?", "%#{contact_name}%") }
scope :with_volumes, -> {
left_joins(donations: :line_items)
.select("product_drive_participants.*, SUM(COALESCE(line_items.quantity, 0)) AS volume")
Expand Down
33 changes: 33 additions & 0 deletions app/models/view/product_drive_participants.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
module View
class ProductDriveParticipants
attr_reader :filters, :params, :participants

def initialize(params:, organization:)
@params = params
@filters = filter_params(params)

@participants = organization
.product_drive_participants
.includes(:donations)
.with_volumes
.class_filter(filters)
.order(:business_name)
end

def filter_params(params = {})
if params.key?(:filters)
params.require(:filters).permit(:by_business_name, :by_contact_name)
else
{}
end
end

def selected_business_name
filters[:by_business_name]
end

def selected_contact_name
filters[:by_contact_name]
end
end
end
36 changes: 33 additions & 3 deletions app/views/product_drive_participants/index.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,36 @@
</div><!-- /.container-fluid -->
</section>

<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<div class="card card-primary">
<div class="card-header">
<h3 class="card-title">Product Drive Participants Filters</h3>
</div>
<div class="card-body">
<%= form_tag(product_drive_participants_path, method: :get) do |f| %>
<div class="row">
<div class="form-group col-lg-3 col-md-4 col-sm-6 col-xs-12">
<%= filter_text(label: "Filter By Business Name", scope: :by_business_name, selected: @products.selected_business_name) %>
</div>
<div class="form-group col-lg-3 col-md-4 col-sm-6 col-xs-12">
<%= filter_text(label: "Filter By Contact Name", scope: :by_contact_name, selected: @products.selected_contact_name) %>
</div>
</div>
</div>
<div class="card-footer">
<%= filter_button %>
<%= clear_filter_button %>
</div>
<% end %>
</div>
</div>
<div class="col-md-6">
</div>
</div>
</div>

<section class="content">
<div class="container-fluid">
<div class="row">
Expand All @@ -31,8 +61,8 @@
<div class="card card-primary">
<div class="card-footer">
<div class="pull-right">
<%= modal_button_to("#csvImportModal", {icon: "upload", text: "Import Product Drive Participants", size: "md"}) if @product_drive_participants.empty? %>
<%= download_button_to(product_drive_participants_path(format: :csv, filters: filter_params.merge(date_range: date_range_params)), {text: "Export Product Drive Participants", size: "md"}) if @product_drive_participants.any? %>
<%= modal_button_to("#csvImportModal", {icon: "upload", text: "Import Product Drive Participants", size: "md"}) if @products.participants.empty? %>
<%= download_button_to(product_drive_participants_path(format: :csv, filters: filter_params.merge(date_range: date_range_params)), {text: "Export Product Drive Participants", size: "md"}) if @products.participants.any? %>

<%= new_button_to new_product_drive_participant_path, text: "New Product Drive Participant" %>
</div>
Expand Down Expand Up @@ -64,7 +94,7 @@
</tr>
</thead>
<tbody>
<%= render partial: "product_drive_participant_row", collection: @product_drive_participants %>
<%= render partial: "product_drive_participant_row", collection: @products.participants %>
</tbody>
</table>
</div>
Expand Down
20 changes: 20 additions & 0 deletions spec/models/product_drive_participant_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,26 @@
expect(subject.first.volume).to eq(10)
end
end

describe ".by_business_name" do
it "returns the product drive participant with a given business name" do
cats_biz = create(:product_drive_participant, business_name: "Cats")
another_cats_biz = create(:product_drive_participant, business_name: "I like cats")
create(:product_drive_participant, business_name: "Dogs")

expect(ProductDriveParticipant.by_business_name("Cats")).to match_array([cats_biz, another_cats_biz])
end
end

describe ".by_contact_name" do
it "returns the product drive participant with a given contact name" do
eleanor = create(:product_drive_participant, contact_name: "Eleanor Shellstrop")
donna = create(:product_drive_participant, contact_name: "Donna Shellstrop")
create(:product_drive_participant, contact_name: "Jason Mendoza")

expect(ProductDriveParticipant.by_contact_name("Shellstrop")).to match_array([eleanor, donna])
end
end
end

context "Methods" do
Expand Down
21 changes: 21 additions & 0 deletions spec/models/view/product_drive_participants_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
RSpec.describe View::ProductDriveParticipants do
describe "selected filter params" do
it "returns the given filter params" do
organization = build(:organization)
build(:product_drive_participant, organization:)
params = ActionController::Parameters.new(
{
filters: {
by_business_name: "The Good Place",
by_contact_name: "Jason Mendoza"
}
}
).permit!

requests = View::ProductDriveParticipants.new(params:, organization:)

expect(requests.selected_business_name).to eq("The Good Place")
expect(requests.selected_contact_name).to eq("Jason Mendoza")
end
end
end
40 changes: 39 additions & 1 deletion spec/requests/product_drive_participants_requests_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
let(:organization) { create(:organization) }
let(:user) { create(:user, organization: organization) }

context "While signed in" do
context "when signed in" do
before do
sign_in(user)
end
Expand All @@ -25,6 +25,44 @@
let(:response_format) { 'csv' }

it { is_expected.to be_successful }

it "exports the filtered results" do
create(:product_drive_participant, business_name: "A business named after cats")
create(:product_drive_participant, business_name: "Dogs are cool")

get product_drive_participants_path(format: :csv, params: {filters: { by_business_name: 'cats'}})

csv = CSV.parse(response.body, headers: true)

expect(csv.count).to eq(1)
expect(csv.first["Business Name"]).to eq("A business named after cats")
end
end

context "when filtering by business name" do
it 'displays only results that matches the business name' do
create(:product_drive_participant, business_name: "A business named after cats")
create(:product_drive_participant, business_name: "Dogs are cool")

get product_drive_participants_path(filters: {by_business_name: 'Cats'})

expect(response).to be_successful
expect(response.body).to include("Cats")
expect(response.body).not_to include("Dogs")
end
end

context "when filtering by contact name" do
it 'displays only results that matches the contact name' do
create(:product_drive_participant, contact_name: "Bob Cat")
create(:product_drive_participant, contact_name: "Freddie the dog")

get product_drive_participants_path(filters: {by_contact_name: 'Cats'})

expect(response).to be_successful
expect(response.body).to include("Cats")
expect(response.body).not_to include("Dogs")
end
end
end

Expand Down
Loading