diff --git a/app/views/spree/admin/reports/users_and_enterprises.html.haml b/app/views/spree/admin/reports/users_and_enterprises.html.haml index d6b4332d3a..6820ee04b1 100644 --- a/app/views/spree/admin/reports/users_and_enterprises.html.haml +++ b/app/views/spree/admin/reports/users_and_enterprises.html.haml @@ -1,32 +1,27 @@ --# = form_tag spree.users_and_enterprises_reports_url do |f| --# %br --# = label_tag nil, "Enterprise: " --# = select_tag(:distributor_id, --# options_from_collection_for_select(@distributors, :id, :name, params[:distributor_id]), --# :include_blank => true) --# --# %br --# = label_tag nil, "User: " --# = select_tag(:supplier_id, --# options_from_collection_for_select(@suppliers, :id, :name, params[:supplier_id]), --# :include_blank => true) --# --# -# Might need this later if we add different kinds of reports --# -# %br --# -# = label_tag nil, "Report Type: " --# -# = select_tag(:report_type, options_for_select(@report_types, params[:report_type])) --# --# %br --# %br --# = check_box_tag :csv --# = label_tag :csv, "Download as csv" --# %br --# = button t(:search) --# %br --# %br -%table += form_tag spree.users_and_enterprises_admin_reports_url do |f| + .row + .alpha.two.columns= label_tag nil, "Enterprises: " + .omega.fourteen.columns= select_tag(:enterprise_id_in, options_from_collection_for_select(Enterprise.all, :id, :name, params[:enterprise_id_in].andand.split(",")), {class: "select2 fullwidth", multiple: true}) + + .row + .alpha.two.columns= label_tag nil, "Users: " + .omega.fourteen.columns= select_tag(:user_id_in, options_from_collection_for_select(Spree::User.all, :id, :email, params[:user_id_in].andand.split(",")), {class: "select2 fullwidth", multiple: true}) + + -# Might need this later if we add different kinds of reports + -# .row + -# .alpha.two.columns= label_tag nil, "Report Type: " + -# .omega.fourteen.columns= select_tag(:report_type, options_for_select(@report_types, params[:report_type])) + + .row + = check_box_tag :csv + = label_tag :csv, "Download as csv" + .row + = button t(:search) +%br +%br +%table#users_and_enterprises %thead - %trs + %tr - @report.header.each do |heading| %th=heading %tbody diff --git a/lib/open_food_network/users_and_enterprises_report.rb b/lib/open_food_network/users_and_enterprises_report.rb index e3686cbacf..a501c505f0 100644 --- a/lib/open_food_network/users_and_enterprises_report.rb +++ b/lib/open_food_network/users_and_enterprises_report.rb @@ -3,6 +3,10 @@ module OpenFoodNetwork attr_reader :params def initialize(params = {}) @params = params + + # Convert arrays of ids to comma delimited strings + @params[:enterprise_id_in] = @params[:enterprise_id_in].join(',') if @params[:enterprise_id_in].kind_of? Array + @params[:user_id_in] = @params[:user_id_in].join(',') if @params[:user_id_in].kind_of? Array end def header @@ -29,21 +33,29 @@ module OpenFoodNetwork end def owners_and_enterprises - ActiveRecord::Base.connection.execute("SELECT enterprises.name, enterprises.sells, enterprises.is_primary_producer, enterprises.confirmed_at, + query = "SELECT enterprises.name, enterprises.sells, enterprises.is_primary_producer, enterprises.confirmed_at, 'owns' AS relationship_type, owners.email as user_email FROM enterprises - LEFT JOIN spree_users AS owners ON owners.id=enterprises.owner_id ORDER BY enterprises.name DESC" ) - .to_a + LEFT JOIN spree_users AS owners ON owners.id=enterprises.owner_id + WHERE enterprises.id IS NOT NULL + #{ params[:enterprise_id_in].present? ? "AND enterprises.id IN (#{ params[:enterprise_id_in] })" : "" } + #{ params[:user_id_in].present? ? "AND owners.id IN (#{ params[:user_id_in] })" : "" } + ORDER BY enterprises.name DESC" + + ActiveRecord::Base.connection.execute(query).to_a end def managers_and_enterprises - ActiveRecord::Base.connection.execute("SELECT enterprises.name, enterprises.sells, enterprises.is_primary_producer, enterprises.confirmed_at, + query = "SELECT enterprises.name, enterprises.sells, enterprises.is_primary_producer, enterprises.confirmed_at, 'manages' AS relationship_type, managers.email as user_email FROM enterprises LEFT JOIN enterprise_roles ON enterprises.id=enterprise_roles.enterprise_id LEFT JOIN spree_users AS managers ON enterprise_roles.user_id=managers.id WHERE enterprise_id IS NOT NULL + #{ params[:enterprise_id_in].present? ? "AND enterprise_id IN (#{ params[:enterprise_id_in] })" : "" } AND user_id IS NOT NULL - ORDER BY enterprises.name DESC, user_email DESC") - .to_a + #{ params[:user_id_in].present? ? "AND user_id IN (#{ params[:user_id_in] })" : "" } + ORDER BY enterprises.name DESC, user_email DESC" + + ActiveRecord::Base.connection.execute(query).to_a end def users_and_enterprises diff --git a/spec/features/admin/reports_spec.rb b/spec/features/admin/reports_spec.rb index 327ce7590a..817f0ad9c4 100644 --- a/spec/features/admin/reports_spec.rb +++ b/spec/features/admin/reports_spec.rb @@ -166,4 +166,50 @@ feature %q{ ].sort end end + + describe "users and enterprises report" do + let!(:enterprise1) { create( :enterprise, owner: create_enterprise_user ) } + let!(:enterprise2) { create( :enterprise, owner: create_enterprise_user ) } + let!(:enterprise3) { create( :enterprise, owner: create_enterprise_user ) } + + before do + enterprise3.enterprise_roles.build( user: enterprise1.owner ).save + + login_to_admin_section + click_link 'Reports' + + click_link 'Users & Enterprises' + end + + it "shows users and enterprises report" do + rows = find("table#users_and_enterprises").all("tr") + table = rows.map { |r| r.all("th,td").map { |c| c.text.strip }[0..2] } + + table.sort.should == [ + [ "User", "Relationship", "Enterprise" ], + [ enterprise1.owner.email, "owns", enterprise1.name ], + [ enterprise1.owner.email, "manages", enterprise1.name ], + [ enterprise2.owner.email, "owns", enterprise2.name ], + [ enterprise2.owner.email, "manages", enterprise2.name ], + [ enterprise3.owner.email, "owns", enterprise3.name ], + [ enterprise3.owner.email, "manages", enterprise3.name ], + [ enterprise1.owner.email, "manages", enterprise3.name ] + ].sort + end + + it "filters the list" do + select enterprise3.name, from: "enterprise_id_in" + select enterprise1.owner.email, from: "user_id_in" + + click_button "Search" + + rows = find("table#users_and_enterprises").all("tr") + table = rows.map { |r| r.all("th,td").map { |c| c.text.strip }[0..2] } + + table.sort.should == [ + [ "User", "Relationship", "Enterprise" ], + [ enterprise1.owner.email, "manages", enterprise3.name ] + ].sort + end + end end diff --git a/spec/lib/open_food_network/users_and_enterprises_report.rb b/spec/lib/open_food_network/users_and_enterprises_report.rb index 11de231871..cf1676492f 100644 --- a/spec/lib/open_food_network/users_and_enterprises_report.rb +++ b/spec/lib/open_food_network/users_and_enterprises_report.rb @@ -1,8 +1,8 @@ require 'spec_helper' - module OpenFoodNetwork describe OrderAndDistributorReport do + include AuthenticationWorkflow describe "users_and_enterprises" do let!(:owners_and_enterprises) { double(:owners_and_enterprises) } @@ -52,5 +52,65 @@ module OpenFoodNetwork expect(subject.sort uae_mock).to eq [ uae_mock[0], uae_mock[1], uae_mock[2] ] end end + + describe "filtering results" do + let!(:enterprise1) { create(:enterprise, owner: create_enterprise_user ) } + let!(:enterprise2) { create(:enterprise, owner: create_enterprise_user ) } + + describe "for owners and enterprises" do + describe "by enterprise id" do + let!(:params) { { enterprise_id_in: [enterprise1.id.to_s] } } + let!(:subject) { OpenFoodNetwork::UsersAndEnterprisesReport.new params } + + it "excludes enterprises that are not explicitly requested" do + results = subject.owners_and_enterprises.to_a.map{ |oae| oae["name"] } + expect(results).to include enterprise1.name + expect(results).to_not include enterprise2.name + end + end + + describe "by user id" do + let!(:params) { { user_id_in: [enterprise1.owner.id.to_s] } } + let!(:subject) { OpenFoodNetwork::UsersAndEnterprisesReport.new params } + + it "excludes enterprises that are not explicitly requested" do + results = subject.owners_and_enterprises.to_a.map{ |oae| oae["name"] } + expect(results).to include enterprise1.name + expect(results).to_not include enterprise2.name + end + end + end + + describe "for managers and enterprises" do + describe "by enterprise id" do + let!(:params) { { enterprise_id_in: [enterprise1.id.to_s] } } + let!(:subject) { OpenFoodNetwork::UsersAndEnterprisesReport.new params } + + it "excludes enterprises that are not explicitly requested" do + results = subject.managers_and_enterprises.to_a.map{ |mae| mae["name"] } + expect(results).to include enterprise1.name + expect(results).to_not include enterprise2.name + end + end + + describe "by user id" do + let!(:manager1) { create_enterprise_user } + let!(:manager2) { create_enterprise_user } + let!(:params) { { user_id_in: [manager1.id.to_s] } } + let!(:subject) { OpenFoodNetwork::UsersAndEnterprisesReport.new params } + + before do + enterprise1.enterprise_roles.build(user: manager1).save + enterprise2.enterprise_roles.build(user: manager2).save + end + + it "excludes enterprises whose managers are not explicitly requested" do + results = subject.managers_and_enterprises.to_a.map{ |mae| mae["name"] } + expect(results).to include enterprise1.name + expect(results).to_not include enterprise2.name + end + end + end + end end end \ No newline at end of file