Commit 1bbebba9a9451135d0421c4dfcf958447373059e
1 parent
02ec23ee
Exists in
master
and in
28 other branches
ActionItem485: listing upcoming events
plus filtering events by month and year in calendar view git-svn-id: https://svn.colivre.coop.br/svn/noosfero/trunk@2166 3f533792-8f58-4932-b0fe-aaf55b0a4547
Showing
5 changed files
with
108 additions
and
10 deletions
Show diff stats
app/controllers/public/search_controller.rb
| ... | ... | @@ -89,24 +89,28 @@ class SearchController < ApplicationController |
| 89 | 89 | def load_product_categories_menu(asset) |
| 90 | 90 | @results[asset].uniq! |
| 91 | 91 | @categories_menu = ProductCategory.menu_categories(@product_category, environment).map do |cat| |
| 92 | - hits = @finder.count(asset, @filtered_query, calculate_find_options(asset, nil, nil, cat, @region, params[:radius])) | |
| 92 | + hits = @finder.count(asset, @filtered_query, calculate_find_options(asset, nil, nil, cat, @region, params[:radius], nil, nil)) | |
| 93 | 93 | childs = [] |
| 94 | 94 | # REFACTOR DUPLICATED CODE inner loop doing the same thing that outter loop |
| 95 | 95 | childs = cat.children.map do |child| |
| 96 | - child_hits = @finder.count(asset, @filtered_query, calculate_find_options(asset, nil, nil, child, @region, params[:radius])) | |
| 96 | + child_hits = @finder.count(asset, @filtered_query, calculate_find_options(asset, nil, nil, child, @region, params[:radius], nil, nil)) | |
| 97 | 97 | [child, child_hits] |
| 98 | 98 | end.select{|child, child_hits| child_hits > 0 } |
| 99 | 99 | [cat, hits, childs] |
| 100 | 100 | end.select{|cat, hits| hits > 0 } |
| 101 | 101 | end |
| 102 | 102 | |
| 103 | - def calculate_find_options(asset, limit, page, product_category, region, radius) | |
| 103 | + def calculate_find_options(asset, limit, page, product_category, region, radius, year, month) | |
| 104 | 104 | |
| 105 | 105 | result = { :product_category => product_category, :per_page => limit, :page => page } |
| 106 | 106 | if [:enterprises, :people].include?(asset) && region |
| 107 | 107 | result.merge!(:within => radius, :region => region.id) |
| 108 | 108 | end |
| 109 | 109 | |
| 110 | + if month || year | |
| 111 | + result[:date_range] = Event.date_range(year, month) | |
| 112 | + end | |
| 113 | + | |
| 110 | 114 | result |
| 111 | 115 | end |
| 112 | 116 | |
| ... | ... | @@ -154,7 +158,7 @@ class SearchController < ApplicationController |
| 154 | 158 | |
| 155 | 159 | SEARCH_IN.select { |key,description| @searching[key] }.each do |key, description| |
| 156 | 160 | @order << key |
| 157 | - @results[key] = @finder.find(key, @filtered_query, calculate_find_options(key, limit, params[:page], @product_category, @region, params[:radius])) | |
| 161 | + @results[key] = @finder.find(key, @filtered_query, calculate_find_options(key, limit, params[:page], @product_category, @region, params[:radius], params[:year], params[:month])) | |
| 158 | 162 | @names[key] = gettext(description) |
| 159 | 163 | end |
| 160 | 164 | |
| ... | ... | @@ -184,7 +188,7 @@ class SearchController < ApplicationController |
| 184 | 188 | [ :people, _('Newer people'), @finder.recent('people', limit) ], |
| 185 | 189 | [ :enterprises, _('Newer enterprises'), @finder.recent('enterprises', limit) ], |
| 186 | 190 | [ :products, ('Newer products'), @finder.recent('products', limit) ], |
| 187 | - [ :events, _('Near events TODO'), @finder.current_events(params[:year], params[:month], {:per_page => limit}) ], | |
| 191 | + [ :events, _('Upcoming events'), @finder.upcoming_events({:per_page => limit}) ], | |
| 188 | 192 | [ :communities, _('Newer communities'), @finder.recent('communities', limit) ], |
| 189 | 193 | [ :articles, _('Newer articles'), @finder.recent('articles', limit) ], |
| 190 | 194 | [ :most_commented_articles, _('Most commented articles'), @finder.most_commented_articles(limit) ] | ... | ... |
app/models/category_finder.rb
| ... | ... | @@ -15,12 +15,14 @@ class CategoryFinder |
| 15 | 15 | options.delete(:within) |
| 16 | 16 | end |
| 17 | 17 | |
| 18 | + date_range = options.delete(:date_range) | |
| 19 | + | |
| 18 | 20 | options = {:page => 1, :per_page => options.delete(:limit)}.merge(options) |
| 19 | 21 | if query.blank? |
| 20 | - asset_class(asset).paginate(:all, options_for_find(asset_class(asset), {:order => "created_at desc, #{asset_table(asset)}.id desc"}.merge(options))) | |
| 22 | + asset_class(asset).paginate(:all, options_for_find(asset_class(asset), {:order => "created_at desc, #{asset_table(asset)}.id desc"}.merge(options), date_range)) | |
| 21 | 23 | else |
| 22 | 24 | ferret_options = {:page => options.delete(:page), :per_page => options.delete(:per_page)} |
| 23 | - asset_class(asset).find_by_contents(query, ferret_options, options_for_find(asset_class(asset), options)) | |
| 25 | + asset_class(asset).find_by_contents(query, ferret_options, options_for_find(asset_class(asset), options, date_range)) | |
| 24 | 26 | end |
| 25 | 27 | end |
| 26 | 28 | |
| ... | ... | @@ -46,9 +48,15 @@ class CategoryFinder |
| 46 | 48 | Event.paginate(:all, {:include => :categories, :conditions => { 'categories.id' => category_id, :start_date => range }}.merge(options)) |
| 47 | 49 | end |
| 48 | 50 | |
| 51 | + def upcoming_events(options = {}) | |
| 52 | + options = { :page => 1}.merge(options) | |
| 53 | + | |
| 54 | + Event.paginate(:all, {:include => :categories, :conditions => [ 'categories.id = ? and start_date >= ?', category_id, Date.today ], :order => :start_date }.merge(options)) | |
| 55 | + end | |
| 56 | + | |
| 49 | 57 | protected |
| 50 | 58 | |
| 51 | - def options_for_find(klass, options={}) | |
| 59 | + def options_for_find(klass, options={}, date_range = nil) | |
| 52 | 60 | if defined? options[:product_category] |
| 53 | 61 | prod_cat = options.delete(:product_category) |
| 54 | 62 | # FIXME this is SLOOOOW |
| ... | ... | @@ -64,8 +72,16 @@ class CategoryFinder |
| 64 | 72 | else |
| 65 | 73 | {:joins => 'inner join categories_profiles on products.enterprise_id = categories_profiles.profile_id', :conditions => ['categories_profiles.category_id = (?)', category_id]}.merge!(options) |
| 66 | 74 | end |
| 67 | - when 'Article', 'Event' | |
| 75 | + when 'Article' | |
| 68 | 76 | {:joins => 'inner join articles_categories on (articles_categories.article_id = articles.id)', :conditions => ['articles_categories.category_id = (?)', category_id]}.merge!(options) |
| 77 | + when 'Event' | |
| 78 | + conditions = | |
| 79 | + if date_range | |
| 80 | + ['articles_categories.category_id = (?) and start_date between ? and ?', category_id, date_range.first, date_range.last] | |
| 81 | + else | |
| 82 | + ['articles_categories.category_id = (?) ', category_id ] | |
| 83 | + end | |
| 84 | + {:joins => 'inner join articles_categories on (articles_categories.article_id = articles.id)', :conditions => conditions}.merge!(options) | |
| 69 | 85 | when 'Enterprise' |
| 70 | 86 | if prod_cat_ids |
| 71 | 87 | {:joins => 'inner join categories_profiles on (categories_profiles.profile_id = profiles.id) inner join products on (products.enterprise_id = profiles.id)', :conditions => ['categories_profiles.category_id = (?) and products.product_category_id in (?)', category_id, prod_cat_ids]}.merge!(options) | ... | ... |
app/models/environment_finder.rb
| ... | ... | @@ -15,6 +15,8 @@ class EnvironmentFinder |
| 15 | 15 | product_category = options.delete(:product_category) |
| 16 | 16 | product_category_ids = product_category.map_traversal(&:id) if product_category |
| 17 | 17 | |
| 18 | + date_range = options.delete(:date_range) | |
| 19 | + | |
| 18 | 20 | options = {:page => 1, :per_page => options.delete(:limit)}.merge(options) |
| 19 | 21 | if query.blank? |
| 20 | 22 | options = {:order => 'created_at desc, id desc'}.merge(options) |
| ... | ... | @@ -23,7 +25,11 @@ class EnvironmentFinder |
| 23 | 25 | elsif product_category && asset == :enterprises |
| 24 | 26 | @environment.send(asset).paginate(:all, options.merge(:order => 'profiles.created_at desc, profiles.id desc', :include => 'products', :conditions => ['products.product_category_id in (?)', product_category_ids])) |
| 25 | 27 | else |
| 26 | - @environment.send(asset).paginate(:all, options) | |
| 28 | + if (asset == :events) && date_range | |
| 29 | + @environment.send(asset).paginate(:all, options.merge(:conditions => { :start_date => date_range})) | |
| 30 | + else | |
| 31 | + @environment.send(asset).paginate(:all, options) | |
| 32 | + end | |
| 27 | 33 | end |
| 28 | 34 | else |
| 29 | 35 | ferret_options = {:page => options.delete(:page), :per_page => options.delete(:per_page)} | ... | ... |
test/functional/search_controller_test.rb
| ... | ... | @@ -647,6 +647,50 @@ class SearchControllerTest < Test::Unit::TestCase |
| 647 | 647 | assert_not_includes assigns(:results)[:events], ev3 |
| 648 | 648 | end |
| 649 | 649 | |
| 650 | + should 'list events for a given month' do | |
| 651 | + person = create_user('testuser').person | |
| 652 | + | |
| 653 | + create_event(person, :name => 'upcoming event 1', :category_ids => [@category.id], :start_date => Date.new(2008, 1, 25)) | |
| 654 | + create_event(person, :name => 'upcoming event 2', :category_ids => [@category.id], :start_date => Date.new(2008, 2, 27)) | |
| 655 | + | |
| 656 | + get :assets, :asset => 'events', :year => '2008', :month => '1' | |
| 657 | + | |
| 658 | + assert_equal [ 'upcoming event 1' ], assigns(:results)[:events].map(&:name) | |
| 659 | + end | |
| 660 | + | |
| 661 | + should 'list events for a given month in a specific category' do | |
| 662 | + person = create_user('testuser').person | |
| 663 | + | |
| 664 | + create_event(person, :name => 'upcoming event 1', :category_ids => [@category.id], :start_date => Date.new(2008, 1, 25)) | |
| 665 | + create_event(person, :name => 'upcoming event 2', :category_ids => [@category.id], :start_date => Date.new(2008, 2, 27)) | |
| 666 | + | |
| 667 | + get :assets, :asset => 'events', :category_path => [ 'my-category' ], :year => '2008', :month => '1' | |
| 668 | + | |
| 669 | + assert_equal [ 'upcoming event 1' ], assigns(:results)[:events].map(&:name) | |
| 670 | + end | |
| 671 | + | |
| 672 | + should 'list upcoming events in a specific category' do | |
| 673 | + person = create_user('testuser').person | |
| 674 | + | |
| 675 | + # today is January 15th, 2008 | |
| 676 | + Date.expects(:today).returns(Date.new(2008,1,15)).at_least_once | |
| 677 | + | |
| 678 | + # in category, but in the past | |
| 679 | + create_event(person, :name => 'past event', :category_ids => [@category.id], :start_date => Date.new(2008, 1, 1)) | |
| 680 | + | |
| 681 | + # in category, upcoming | |
| 682 | + create_event(person, :name => 'upcoming event 1', :category_ids => [@category.id], :start_date => Date.new(2008, 1, 25)) | |
| 683 | + create_event(person, :name => 'upcoming event 2', :category_ids => [@category.id], :start_date => Date.new(2008, 1, 27)) | |
| 684 | + | |
| 685 | + # not in category | |
| 686 | + create_event(person, :name => 'event not in category') | |
| 687 | + | |
| 688 | + get :category_index, :category_path => ['my-category'] | |
| 689 | + | |
| 690 | + assert_equal [ 'upcoming event 1', 'upcoming event 2' ], assigns(:results)[:events].map(&:name) | |
| 691 | + end | |
| 692 | + | |
| 693 | + | |
| 650 | 694 | %w[ people enterprises articles events communities products ].each do |asset| |
| 651 | 695 | should "render asset-specific template when searching for #{asset}" do |
| 652 | 696 | get :index, :find_in => [ asset ] | ... | ... |
test/unit/category_finder_test.rb
| ... | ... | @@ -290,6 +290,34 @@ class CategoryFinderTest < ActiveSupport::TestCase |
| 290 | 290 | assert_respond_to events, :total_entries |
| 291 | 291 | end |
| 292 | 292 | |
| 293 | + should 'list upcoming events' do | |
| 294 | + person = create_user('testuser').person | |
| 295 | + | |
| 296 | + Date.expects(:today).returns(Date.new(2008, 1, 15)).at_least_once | |
| 297 | + | |
| 298 | + past_event = Event.create!(:name => 'past event', :profile => person, :start_date => Date.new(2008,1,1), :category_ids => [@category.id]) | |
| 299 | + | |
| 300 | + # event 2 is created after, but must be listed before (since it happens before) | |
| 301 | + upcoming_event_2 = Event.create!(:name => 'upcoming event 2', :profile => person, :start_date => Date.new(2008,1,25), :category_ids => [@category.id]) | |
| 302 | + upcoming_event_1 = Event.create!(:name => 'upcoming event 1', :profile => person, :start_date => Date.new(2008,1,20), :category_ids => [@category.id]) | |
| 303 | + not_in_category = Event.create!(:name => 'e1', :profile => person, :start_date => Date.new(2008,1,20)) | |
| 304 | + | |
| 305 | + assert_equal [upcoming_event_1, upcoming_event_2], @finder.upcoming_events | |
| 306 | + end | |
| 307 | + | |
| 308 | + should 'limit events' do | |
| 309 | + person = create_user('testuser').person | |
| 310 | + | |
| 311 | + Date.expects(:today).returns(Date.new(2008, 1, 15)).at_least_once | |
| 312 | + | |
| 313 | + past_event = Event.create!(:name => 'past event', :profile => person, :start_date => Date.new(2008,1,1), :category_ids => [@category.id]) | |
| 314 | + upcoming_event_1 = Event.create!(:name => 'upcoming event 1', :profile => person, :start_date => Date.new(2008,1,20), :category_ids => [@category.id]) | |
| 315 | + upcoming_event_2 = Event.create!(:name => 'upcoming event 2', :profile => person, :start_date => Date.new(2008,1,25), :category_ids => [@category.id]) | |
| 316 | + not_in_category = Event.create!(:name => 'e1', :profile => person, :start_date => Date.new(2008,1,20)) | |
| 317 | + | |
| 318 | + assert_equal [upcoming_event_1], @finder.upcoming_events(:per_page => 1) | |
| 319 | + end | |
| 320 | + | |
| 293 | 321 | should 'find person and enterprise in category by radius and region even without query' do |
| 294 | 322 | cat = Category.create!(:name => 'test category', :environment => Environment.default) |
| 295 | 323 | finder = CategoryFinder.new(cat) | ... | ... |