Skip to content

Instantly share code, notes, and snippets.

@codesnik
Created February 26, 2010 22:58
Show Gist options
  • Save codesnik/316283 to your computer and use it in GitHub Desktop.
Save codesnik/316283 to your computer and use it in GitHub Desktop.
WTF ZOMG controller
class CatalogueController < ApplicationController
@@rows_on_page = 50
@@companies_on_page = 20
def firms
# Возвращаем "304 Not Modified" если страница не устарела
if industry.cached_level >= 2 || industry.leaf?
if params[:format] != 'xls'
# если выводится список компаний (причем не в ExCel)
self.http_headers_section = :with_rows
return if send_not_modified
end
else
# если не выводится список компаний
self.http_headers_section = :without_rows
end
# мы показываем фирмы в каталоге, начиная со второго уровня,
# либо если рубрика и так является нодой,
# либо если мы ищем поиском что-то
#load_regions
return not_found if industry.nil?
@search_section = "firms" # установка глобальной переменной для формы поиска
# TODO отрефакторить magic number 20
@number = params[:page] ? 20 * (params[:page].to_i - 1) : 0
# поиск у нас происходит добавлением параметра "q", поэтому мы вынесем поиск
# в отдельное место
return searchfirms if !params[:q].nil? && params[:q] != ""
page_title_section = industry.level == 0 ? '' : '_rubric'
set_title_key("title#{page_title_section}")
set_header_key("header#{page_title_section}")
set_description_key("description#{page_title_section}")
set_title_variables(title_header_descr_values)
# подрубрики
@subrubrics = industry.direct_children
companies_count = Industry.do_count_companies(current_region, @subrubrics) #Получаем кол-во компаний в текущем регионе для каждой их подрубрик
@subrubrics.each {|r| r.set_company_count(current_region, companies_count[r.id] ||= 0)}
# удалить из полученного результата все рубрики, у которых нет компаний и которые не являются симлинком
@subrubrics = @subrubrics.delete_if { |o| o.company_count(current_region) == 0 && o.link_to == nil }
if industry.cached_level >= 2 || industry.leaf?
# экспорт в эксель
if params[:format] == 'xls'
@companies = Company.search('',
# TODO отрефакторить magic number 1000
:per_page => 1000, # TODO: пока ограничимся этим максимумом
:with => firms_query_conditions,
:order => :title_ord,
:sort_mode => :asc)
exporter = ExportExcel::Companies.new(@companies, {:host => request.host})
send_data exporter.export, :filename => 'pulscen-companies.xls', :content_type => "application/xls"
return
else
@companies = load_companies_by_ids(Company.search_for_ids('',
:page => params[:page],
# TODO отрефакторить magic number 20
:per_page => @@companies_on_page,
:with => firms_query_conditions,
:order => :title_ord, :sort_mode => :asc))
@letters = Company.list_letters('', firms_query_conditions)
end
else
# если мы не показываем компании, то показываем список последних компаний
@last_companies = Company.search('',
:page => 1,
# TODO отрефакторить magic number 90 и 60
:per_page => industry.root? ? 90 : 60,
:with => firms_query_conditions,
:order => :created_at,
:sort_mode => :desc)
end
end
def search_redirect
# если нам передали флаг "искать в рубрике" и "путь до рубрики", то надо
# сделать туда редирект
if !params[:rubric].nil?
options = {:q => params[:q]}
route = current_region.default? ? :firms_path : :region_firms_path
options[:region] = current_region.name_lat unless current_region.default?
options[:path] = params[:rubric] if params[:search_in_rubric] && params[:rubric] != "/"
return redirect_to send(route, options)
end
return not_found
end
def searchfirms
page_title_section = '_search'
set_title_key("title#{page_title_section}")
set_header_key("header#{page_title_section}")
set_description_key("description#{page_title_section}")
set_title_variables(title_header_descr_values)
se = Search::SearchQuery.new(params[:q], true)
@search_query = se.prepared
if params[:format] == 'xls'
@companies = Company.search @search_query,
# TODO отрефакторить magic number 1000
:per_page => 1000,
:with => firms_query_conditions
exporter = ExportExcel::Companies.new(@companies, {:host => request.host})
send_data exporter.export, :filename => 'pulscen-companies.xls', :content_type => "application/xls"
return
else
@companies = load_companies_by_ids(Company.search_for_ids(@search_query,
:page => params[:page],
# TODO отрефакторить magic number 20
:per_page => @@companies_on_page,
:with => firms_query_conditions))
set_title_variables(title_header_descr_values.merge({:COUNT => @companies.total_entries}))
end
# когда мы хотим вывести рубрики, то убираем фильтр по первой букве
cond = firms_query_conditions
cond.delete(:first_letter_ord)
@subrubrics = Company.list_industries @search_query, cond
@letters = Company.list_letters @search_query, firms_query_conditions
# чтобы правильно отобразилось общее найденное число
industry.set_company_count(current_region, @companies.total_entries)
render 'firms'
end
def sprosfirms
# Возвращаем "304 Not Modified" если страница не устарела
self.http_headers_section = :with_rows
return if send_not_modified
if check_search
return
end
return try_rubric_with_old_url if rubric.nil?
@count_demand = {:is_demand => true}
advanced_search_mod
load_rubrics(@count_demand)
within = rubric.leaf? || rubric.is_normativka? ? "rubric_id" : "rubric_l#{rubric.level}_id"
set_title_variables(title_header_descr_values)
@predl_count = ThinkingSphinx.search_count(
@search_query,
:with => @count_demand.merge({:regions => [current_region.id], within => rubric.id }),
:classes => [Product, PriceListRow],
:match_mode => :extended
)
@firms_count = ThinkingSphinx.search_count(
@search_query,
:with => @count_demand.merge({:regions => [current_region.id], within => rubric.id }),
:classes => [Product, PriceListRow],
:group => :company_id,
:match_mode => :extended
)
@predl_count = 0 if @predl_count.nil?
@firms_count = 0 if @firms_count.nil?
@firms = nil
if show_rows?
sph_res = ThinkingSphinx.search(
@search_query,
:with => @count_demand.merge({:regions => [current_region.id], within => rubric.id}),
:classes => [Product, PriceListRow],
:page => params[:page],
:per_page => @@rows_on_page,
:match_mode => :extended,
:group_by => "company_id",
:group_function => :attr,
:group_clause => "@count DESC"
)
sph_data = sph_res.results[:matches]
companies_ids = sph_data.collect { |e| e[:attributes]["@groupby"] }
if companies_ids.length == 0
return
end
@firms = Array.new
def @firms.sph_res=(r)
@sph_res = r
end
@firms.sph_res = sph_res
def @firms.total_pages
@sph_res.total_pages
end
def @firms.current_page
@sph_res.current_page
end
def @firms.next_page
@sph_res.next_page
end
def @firms.previous_page
@sph_res.previous_page
end
# load predl count for companies
spros_count = PriceListRow.fast_facet('', :company_id, :with => {:company_id => companies_ids, :is_demand => true})
# stats
stats = CompanyStatisticTotalByMonth.previous_month.find(:all, :conditions => {:company_id => companies_ids}, :select => 'company_id, sum(pages) as sum_pages, sum(visits) as sum_visits', :group => 'company_id')
stats_hash = {}
stats.each do |s|
stats_hash[s.company_id] = {:pages => s.sum_pages.to_i, :visits => s.sum_visits.to_i}
end
# load from db
companies = Company.find(companies_ids, :include => [:company_logo, {:main_address => :city}])
companies_hash = {}
companies.each do |c|
c.spros_count = spros_count[c.id] || 0
companies_hash[c.id] = c
end
sph_data.each { |e|
@firms.push({
:firm => companies_hash[e[:attributes]["@groupby"]],
:count => e[:attributes]["@count"],
:stats => stats_hash[e[:attributes]["@groupby"]] ? stats_hash[e[:attributes]["@groupby"]] : {}
})
}
end
end
def predlfirms
# Возвращаем "304 Not Modified" если страница не устарела
self.http_headers_section = :with_rows
return if send_not_modified
if check_search
return
end
return try_rubric_with_old_url if rubric.nil?
set_title_variables(title_header_descr_values)
@count_demand = {:is_demand => false}
advanced_search_mod
load_rubrics(@count_demand)
within = rubric.leaf? || rubric.is_normativka? ? "rubric_id" : "rubric_l#{rubric.level}_id"
@predl_count = ThinkingSphinx.search_count(
@search_query,
:with => @count_demand.merge({:regions => [current_region.id], within => rubric.id }),
:classes => [Product, PriceListRow],
:match_mode => :extended
)
@firms_count = ThinkingSphinx.search_count(
@search_query,
:with => @count_demand.merge({:regions => [current_region.id], within => rubric.id }),
:classes => [Product, PriceListRow],
:group => :company_id,
:match_mode => :extended
)
@predl_count = 0 if @predl_count.nil?
@firms_count = 0 if @firms_count.nil?
@firms = nil
if show_rows?
sph_res = ThinkingSphinx.search_for_ids(
@search_query,
:with => @count_demand.merge({:regions => [current_region.id], within => rubric.id}),
:classes => [Product, PriceListRow],
:page => params[:page],
:per_page => @@rows_on_page,
:match_mode => :extended,
:group_by => "company_id",
:group_function => :attr,
:group_clause => "packet DESC, @count DESC"
)
sph_data = sph_res.results[:matches]
companies_ids = sph_data.collect { |e| e[:attributes]["@groupby"] }
if companies_ids.length == 0
return
end
@firms = Array.new
def @firms.sph_res=(r)
@sph_res = r
end
@firms.sph_res = sph_res
def @firms.total_pages
@sph_res.total_pages
end
def @firms.current_page
@sph_res.current_page
end
def @firms.next_page
@sph_res.next_page
end
def @firms.previous_page
@sph_res.previous_page
end
# load predl count for companies
predl_count = PriceListRow.fast_facet('', :company_id, :with => {:company_id => companies_ids, :is_demand => false})
# stats
stats = CompanyStatisticTotalByMonth.previous_month.find(:all, :conditions => {:company_id => companies_ids}, :select => 'company_id, sum(pages) as sum_pages, sum(visits) as sum_visits', :group => 'company_id')
stats_hash = {}
stats.each do |s|
stats_hash[s.company_id] = {:pages => s.sum_pages.to_i, :visits => s.sum_visits.to_i}
end
# prod count
prod = Product.fast_facet('', :company_id, :with => {:company_id => companies_ids})
# load from db
companies = Company.find(companies_ids,
:select => 'id, name, packet, has_email',
:include => [:representative, :company_logo, {:main_address => :city}])
companies_hash = {}
companies.each do |c|
c.predl_count = predl_count[c.id] || 0
c.index_products_count = prod[c.id] || 0
companies_hash[c.id] = c
end
sph_data.each { |e|
@firms.push({
:firm => companies_hash[e[:attributes]["@groupby"]],
:count => e[:attributes]["@count"],
:stats => stats_hash[e[:attributes]["@groupby"]] ? stats_hash[e[:attributes]["@groupby"]] : {}
})
}
end
end
# caches_action :spros,
# :expires_in => Conf.general['cache_expire'].minutes,
# :layout => false,
# :cache_path => Proc.new{|controller| controller.params.merge({:region => controller.current_region.name_lat})}
def spros
return try_rubric_with_old_url if rubric.nil?
# Возвращаем "304 Not Modified" если страница не устарела
if show_rows?
self.http_headers_section = :with_rows
return if send_not_modified
else
self.http_headers_section = :without_rows
end
if check_search
return
end
# page title
# page title
if @search_query != ""
page_title_section = '_search'
else
page_title_section = rubric.level == 0 ? '' : '_rubric'
end
set_title_key("title#{page_title_section}")
set_header_key("header#{page_title_section}")
set_description_key("description#{page_title_section}")
set_title_variables(title_header_descr_values)
@cache_key = self.params.merge({:region => current_region.name_lat})
@cache_key.merge!({:region_by_ip => current_region_by_ip.name_lat}) if current_region_by_ip
@cache_expires_in = (show_rows? ? Conf.cache['catalogue']['spros']['with_rows'] : Conf.cache['catalogue']['spros']['without_rows']).minutes
return if fragment_exist?(@cache_key)
#load_regions
#порядок важе - переменную изменять после загрузки регионов
@count_demand = {:is_demand => true}
advanced_search_mod
load_rubrics(@count_demand)
within = "rubric_l#{rubric.cached_level}_id"
with = @count_demand.merge({:regions => [current_region.id], within => rubric.id }.merge(@count_demand))
if params[:format] == 'xls'
exporter = ExportExcel::Goods.new @search_query,
with,
{
:request_uri => url_for(:overwrite_params => {:format => nil}, :only_path => false),
:user_query => params[:q],
:host => request.host
}
send_data exporter.export, :filename => 'pulscen-spros.xls', :content_type => "application/xls"
return
end
@spros_count = PriceListRow.search_count(
@search_query,
:with => with,
:match_mode => :extended
)
@firms_count = PriceListRow.search_count(
@search_query,
:with => with,
:group => :company_id,
:match_mode => :extended
)
@spros_count = 0 if @spros_count.nil?
@firms_count = 0 if @firms_count.nil?
@rows = nil
if show_rows?
@rows = PriceListRow.search(
@search_query,
:with => with,
:page => params[:page],
:per_page => @@rows_on_page,
:match_mode => :extended,
:sort_mode => :extended,
:order => "@relevance DESC, date_order DESC, sort_level ASC, title ASC"
#:order => "@relevance DESC, position ASC"
)
@rows = load_linked_objects_for_rows!(@rows)
end
end
# caches_action_with_content_for :predl,
# :expires_in => Conf.general['cache_expire'].minutes,
# :layout => false,
# :cache_path => Proc.new{|controller| controller.params.merge({:region => controller.current_region.name_lat})}
def predl
return try_rubric_with_old_url if rubric.nil?
# Возвращаем "304 Not Modified" если страница не устарела
if show_rows?
self.http_headers_section = :with_rows
return if send_not_modified
else
self.http_headers_section = :without_rows
end
if check_search
return
end
# page title
page_title_key = ''
if @search_query != ""
page_title_section = '_search'
else
page_title_section = rubric.level == 0 ? '' : '_rubric'
if rubric.level > 0 && !rubric.synonym
page_title_key = '_rubric_no_synonym'
end
end
if current_region.name_lat == 'ru'
if page_title_key != ''
page_title_key += '_no_region'
else
page_title_section += '_no_region'
end
end
set_title_key(page_title_key != "" ? "title#{page_title_key}" : "title#{page_title_section}")
set_header_key("header#{page_title_section}")
set_description_key("description#{page_title_section}")
set_title_variables(title_header_descr_values)
@cache_key = self.params.merge({:region => current_region.name_lat})
@cache_key.merge!(:region_by_ip => current_region_by_ip.name_lat) if current_region_by_ip
@cache_expires_in = (show_rows? ? Conf.cache['catalogue']['predl']['with_rows'] : Conf.cache['catalogue']['predl']['without_rows']).minutes
return if fragment_exist?(@cache_key)
#load_regions
@count_demand = {:is_demand => false}
advanced_search_mod
load_rubrics(@count_demand)
within = rubric.leaf? || rubric.is_normativka? ? "rubric_id" : "rubric_l#{rubric.level}_id"
with = @count_demand.merge({:regions => [current_region.id], within => rubric.id })
if params[:format] == 'xls'
exporter = ExportExcel::Goods.new @search_query,
with,
{
:request_uri => url_for(:overwrite_params => {:format => nil}, :only_path => false),
:user_query => params[:q],
:host => request.host
}
send_data exporter.export, :filename => 'pulscen-predl.xls', :content_type => "application/xls"
return
end
@firms_count = ThinkingSphinx.search_count(
@search_query,
:with => with,
:classes => [Product, PriceListRow],
:group => :company_id,
:match_mode => :extended
)
@firms_count = 0 if @firms_count.nil?
@products_total = @lots_total = 0
@rows = nil
if show_rows?
product_fields = ['id', 'name', 'announce', 'company_id',
'is_exact_price', 'price',
'price_max', "actualized_at"]
current_page = params[:page].to_i || 1
current_page = 1 if current_page < 1
@products = Product.search(
@search_query,
:with => with,
:page => current_page,
:per_page => @@rows_on_page,
:match_mode => :extended,
#:sort_mode => :extended,
:group_by => 'company_id',
:group_function => :attr,
#:order => "@relevance DESC, packet DESC, date_order DESC, title ASC"
:group_clause => "@relevance DESC, packet DESC, date_order DESC, title ASC",
:select => product_fields.join(', ')
)
@products_total = @products.results[:total_found] || 0
if @products.count < @@rows_on_page
offset = ((current_page - 1) * @@rows_on_page) - @products_total
offset = 0 if offset < 0
limit = @@rows_on_page - @products.count
offset = (5000 - limit) if (offset + limit) > 5000
lots_fields = ['id', 'title', 'company_id', 'price', 'price_max', 'is_exact']
@lots = PriceListRow.search(
@search_query,
:with => with,
:offset => offset,
:limit => limit,
:match_mode => :extended,
:sort_mode => :extended,
:order => "is_row ASC, @relevance DESC, date_order DESC, sort_level ASC, title ASC",
:select => lots_fields.join(', ')
#:order => "@relevance DESC, position ASC"
)
@lots_total = @lots.results[:total_found] || 0
else
@lots = []
@lots_total = PriceListRow.search_count(
@search_query,
:with => with,
:match_mode => :extended
) || 0
end
@predl_count = @products_total.to_i + @lots_total.to_i
@rows = @products.to_a + @lots.to_a
@rows = load_linked_objects_for_rows!(@rows.compact)
self.class.total_pages = ([@predl_count, 5000].min.to_f / @@rows_on_page.to_f).ceil
self.class.current_page = current_page
def @rows.total_pages
CatalogueController.total_pages
end
def @rows.current_page
CatalogueController.current_page
end
def @rows.next_page
current_page < total_pages ? current_page + 1 : nil
end
def @rows.previous_page
current_page > 1 ? current_page - 1 : nil
end
else # if !show_rows?
@predl_count = Product.search_count(
@search_query,
:with => with,
:match_mode => :extended,
:group_by => 'company_id',
:group_function => :attr
) + PriceListRow.search_count(
@search_query,
:with => with,
:match_mode => :extended
)
end
#PriceListRow.paginate_all_by_rubric_id @rubric.id, :page => page, :per_page => 50 if rubric.rubric_level >= 3#PriceListRow.by_rubric(rubric).search(:page => page, :per_page => 100) if rubric.rubric_level >= 3
#ThinkingSphinx.search_count(:with => {:regions => [2]}, :classes => [Product, PriceListRow], :index_weights => {Product => 10, PriceListRow => 1})
end
cattr_accessor :total_pages
cattr_accessor :current_page
caches_page :lastgoods, :lastgoods_frontend
def lastgoods_frontend
set_title_variables(title_header_descr_values)
@rows = lastgoods_items(@@rows_on_page, params[:page] || 1)
end
helper_method :lastgoods_items
def lastgoods_items(limit, page, rubric_filter = nil)
min_packet = 2
unless rubric_filter.nil?
field = "rubric_l#{rubric_filter.level}_id"
# cond = ["companies.packet >= ? AND companies.state = ? AND products.state = ? AND products.rubric_l4_id > ? AND products.#{field} = ?", min_packet, 'accepted', 'accepted', 0, rubric_filter.id]
sph_cond = {:packet => min_packet..5, field.to_sym => rubric_filter.id}
else
# cond = ['companies.packet >= ? AND companies.state = ? AND products.state = ? AND products.rubric_l4_id > ?', min_packet, 'accepted', 'accepted', 0]
sph_cond = {:packet => min_packet..5}
end
# Product.paginate(
# :page => page,
# :per_page => limit,
# :order => 'products.created_at DESC',
# :include => {:company => {:main_address => :city}},
# :conditions => cond
# )
Product.search('',
:with => sph_cond,
:sort_mode => :extended,
:order => 'sphinx_internal_id DESC',
:include => {:company => {:main_address => :city}},
:page => page,
:per_page => limit
)
end
def lastgoods
total = 100
portions = 1
if params[:portion] && (portion = (begin Integer params[:portion] rescue nil end))
offset = total * (portion / portions)
limit = total / portions
else
offset = 0
limit = total
end
render :json => {
:without_photo => _lastgoods({:limit => limit, :offset => offset, :with_photo => false}),
:with_photo => _lastgoods({:limit => limit, :offset => offset, :with_photo => true})
}
end
def _lastgoods(options = {})
limit = options[:limit] || 100
offset = options[:offset] || 0
images_cond = options[:with_photo] ? 'images.id IS NULL' : 'images.position = 1'
products = Product.all(
:offset => offset,
:limit => limit,
:include => [:images, {:company => :main_address}],
:conditions => ["NOT (companies.id IS NULL) AND (companies.state != 'deleted') AND companies.packet >= 2 AND " + images_cond],
:order => 'products.created_at DESC'
)
# Ассоциации напрямую неиспользуются ддя того чтобы не плодить по 200 запросов
cities = {}
Address.all(:conditions => {:id => products.map{|p| p.company.main_address.id}.uniq}, :include => :city).map{|a| cities[a.id.to_i] = a.city.name.to_s}
products.map do |p|
{
:title => p.name,
:href => company_product_url(p.company, p),
:firm_title => p.company.name,
:firm_href => company_url(p.company),
#:firm_city => p.company.main_address.city.name,
:firm_city => cities[p.company.main_address.id.to_i], # Ассоциации напрямую неиспользуются ддя того чтобы не плодить по 200 запросов
:image => p.images.first ? p.images.first.img.url : false,
:firm_raiting => @template.raiting_star(p.company)
}
end
end
# def lastgoods
# # json
# response.headers['Content-type'] = "text/plain; charset=utf-8"
# limit = (params[:limit] if params[:limit].to_i > 0 && params[:limit].to_i < 10) || 1
# offset = (params[:offset] if params[:offset].to_i > 0 && params[:offset].to_i < 200) || 0
#
# images_cond = params[:nophotos] ? 'images.id IS NULL' : 'images.position = 1'
#
# products = Product.find(
# :all,
# :limit => limit,
# :offset => offset,
# :include => [:images],
# :joins => [:company, :rubric],
# :conditions => ["companies.state != 'deleted' /*AND companies.packet >= 2*/ AND "+images_cond],
# :order => 'products.created_at DESC'
# )
#
# # prepare data
# data = Array.new
# products.each { |p|
# data.push({
# :title => p.name,
# :href => company_product_url(p.company, p),
# :firm_title => p.company.name,
# :firm_href => company_url(p.company),
# :firm_city => p.company.main_address.city.name,
# :image => p.images.first ? p.images.first.img.url : '/images/firms/pic90x90.gif'
# })
# }
#
# render :text => data.to_json
# end
protected
def show_rows?
# TODO число 2 подозрительное какое-то. надо или комент к методу или вынести в конфиг
rubric.level > 2 || params[:search] || rubric.next_level_normativka
end
def check_search
@search_query = ''
if params[:search] && !params[:q].nil? && params[:q] != ""
if !params[:rubric].nil?
r = Rubric.find(params[:rubric])
route = current_region.default? ? "search#{params[:action]}_path".to_sym : "region_search#{params[:action]}_path".to_sym
options = {:q => params[:q]}
options[:region] = current_region.name_lat unless current_region.default?
if params[:search_in_rubric] && !r.nil? && !r.root?
options[:path] = r.path
# redirect_to url_for(:controller => "catalogue",
# :action => params[:action],
# :q => params[:q],
# :path => r.path,
# :region => current_region.default? ? nil : current_region.name_lat,
# :search => true
# )
# return true
# else
# redirect_to url_for(:controller => "catalogue",
# :action => params[:action],
# :q => params[:q],
# :region => current_region.default? ? nil : current_region.name_lat,
# :search => true
# )
# return true
end
return redirect_to send(route, options)
end
if params[:adv] != "1"
se = Search::SearchQuery.new(params[:q])
else
# в расширенном поиске можно передать раздел, и если этот раздел не равен текущему,
# то надо перенаправить на нужный
if params[:is_demand] == "1" && params[:action] == "predl"
redirect_to url_for(:overwrite_params => {:action => "spros"})
return true
end
if params[:is_demand] != "1" && params[:action] == "spros"
redirect_to url_for(:overwrite_params => {:action => "predl"})
return true
end
if !params[:q].instance_of? HashWithIndifferentAccess
q = {:all => params[:q], :any => "", :without => ""}
else
q = {:all => params[:q][:all], :any => params[:q][:any], :without => params[:q][:without]}
end
se = Search::SearchQueryAdvanced.new(q[:any], q[:all], q[:without])
end
@search_query = se.prepared
end
return false
end
def advanced_search_mod
if params[:search] && params[:adv] == "1"
if params[:price].instance_of? HashWithIndifferentAccess
# макс/мин цена - разные условия
# TODO мин и макс вынести в конфиг
min = 0.0
max = 2000000000.0
if params[:price][:min].to_f > 0
min = params[:price][:min].to_f
end
if params[:price][:max].to_f > 0
max = params[:price][:max].to_f
end
if min > max
min, max = max, min
end
@count_demand[:price_uni] = min..max
end
end
end
def load_rubrics( with_args )
if 0==rubric.level
# если поиск по всем предложениям, то надо
# проверить рубрики, начиная с 2 уровня
# и если на каком-то уровне выяснится, что получилась только одна рубрика,
# то надо сделать редирект туда
if params[:search]
facets = [:rubric_l2_id, :rubric_l3_id, :rubric_l4_id]
sph_data = ThinkingSphinx.facets(
@search_query,
:with => with_args,
:facets => facets,
:classes => [Product, PriceListRow],
:match_mode => :extended
)
redirect_rubric = nil
facets.each { |facet|
data = sph_data[facet]
# delete NULL data
data.delete(0)
if data.length == 1
redirect_rubric = Rubric.find(data.to_a.first[0])
end
}
if !redirect_rubric.nil?
redirect_to url_for(:overwrite_params => {:path => redirect_rubric.path})
return
end
end
if @search_query != ''
@rubrics = load_level3_rubrics_for_search( with_args )
else
@rubrics = load_root_rubrics( with_args )
end
end
if rubric.level > 0
unless @search_query.blank?
@rubrics = load_descendant_rubrics_for_search( with_args )
else
@rubrics = load_descendant_rubrics( with_args )
end
end
end
def load_descendant_rubrics( with_args )
stat_field = 'predl_stat'
stat_field = 'spros_stat' if params[:action] == "spros"
stat_field = 'providers_stat_predl' if params[:action] == "predlfirms"
stat_field = 'providers_stat_spros' if params[:action] == "sprosfirms"
rubrics = Rubric.find_by_sql(['SELECT *, NULL AS prefix_normativka FROM get_catalogue_rubricator(?, ?, ?)', rubric.id, current_region.id, stat_field])
rubrics_result = []
rubrics.each do |r|
if r.cached_level == rubric.cached_level + 1
r.descendants_rubrics = [] # создаем задел под рубрики 3-го уровня
r.rows_count_in_current_region = r.current_region_stats
r.rows_count_in_total = current_region.default? ? nil : r.default_region_stats
rubrics_result << r
else
if rubrics_result.last.id == r.parent_id && !rubrics_result.last.descendants_rubrics.nil?
rubrics_result[rubrics_result.length - 1].descendants_rubrics << r
end
end
end
return rubrics_result
end
def load_descendant_rubrics_for_search( with_args )
# очевидно, что если рубрика и так последняя, то ничего загружать не надо
# рубрика также будет являться последней, ежели её slug будет числом
if rubric.leaf? || rubric.is_normativka? || (rubric.slug =~ /\d+/) != nil
return []
end
# загружаем рубрики дочерние
rubrics_cnt = rubric.children_with_count_in(current_region.id, @search_query, with_args)
unless current_region.default?
rubrics_cnt_total = rubric.children_with_count_in(Region::DEFAULT_REGION, @search_query, with_args)
else
rubrics_cnt_total = {}
end
#debugger
rubric_fields = ['id', 'parent_id', 'title', 'joined_path', 'is_normativka', 'prefix_normativka',
'next_level_normativka', 'lft', 'rgt', 'cached_level']
rubrics = Rubric.find(:all, :select => rubric_fields.join(', '), :conditions => {:id => rubrics_cnt.keys})
# sort by (search = count, listing = lft)
rubrics = rubrics.sort { |a,b|
(@search_query.is_a?(String) && @search_query != "") || rubric.next_level_normativka? ?
rubrics_cnt[b.id] <=> rubrics_cnt[a.id] :
a.lft <=> b.lft
}
result = []
all_children_ids = [] # все IDы рубрик нижнего уровня (мы их загрузим потом и все сразу)
rubrics.each_index do |i|
r = rubrics[i]
next if r.id == rubric.id
rubrics[i].descendants_rubrics = []
children_hash = {}
# подгрузить детяк
unless r.leaf? || r.cached_level == 5 || rubric.next_level_normativka?
children_cnt = r.children_with_count_in(current_region.id, @search_query, with_args)
children_cnt.delete(r.id)
children_cnt.delete(rubric.id)
#load-load-load
unless children_cnt.nil?
# надо отсортировать рубрики по количеству в них найденного
children_cnt_ar = children_cnt.sort {|a,b| b[1] <=> a[1]}[0..7]
children_cnt = {}
children_cnt_ar.each do |a|
children_cnt[a[0]] = a[1]
end
#children = Rubric.find(children_cnt.keys)
all_children_ids << children_cnt.keys
rubrics[i].descendants_rubrics = children_cnt.keys
end
end
rubrics[i].rows_count_in_current_region = rubrics_cnt[r.id]
rubrics[i].rows_count_in_total = rubrics_cnt_total[r.id]
#result.push(rubrics[i])
end
if all_children_ids.length > 0
children_rubrics_hash = {}
Rubric.find(:all, :conditions => {:id => all_children_ids.flatten.uniq}).each do |r| children_rubrics_hash[r.id] = r end
rubrics.each_index do |i|
if !rubrics[i].descendants_rubrics.nil? && rubrics[i].descendants_rubrics.length > 0
children = []
rubrics[i].descendants_rubrics.each do |id|
children << children_rubrics_hash[id] unless children_rubrics_hash[id].nil?
end
rubrics[i].descendants_rubrics = children
end
result << rubrics[i]
end
else
result = rubrics
end
result
end
def load_level3_rubrics_for_search( with_args )
level3_cnt = Rubric.rubrics_l3_with_count_in(current_region.id, @search_query, with_args)
unless current_region.default?
level3_cnt_total = Rubric.rubrics_l3_with_count_in(Region::DEFAULT_REGION, @search_query, with_args.merge(:rubric_l3_id => level3_cnt.keys))
else
level3_cnt_total = {}
end
#load
rubrics = Rubric.find(:all, :conditions => {:id => level3_cnt.keys})
rubrics.each do |r|
r.rows_count_in_current_region = level3_cnt[r.id] # кол-во
r.rows_count_in_total = level3_cnt_total[r.id]
end
rubrics.sort { |a, b| b.rows_count_in_current_region <=> a.rows_count_in_current_region }
end
def load_root_rubrics( with_args )
stat_field = 'predl_stat'
stat_field = 'spros_stat' if params[:action] == "spros"
stat_field = 'providers_stat_predl' if params[:action] == "predlfirms"
stat_field = 'providers_stat_spros' if params[:action] == "sprosfirms"
max_level = params[:action] == "spros" || params[:action] == "sprosfirms" ? 2 : 3
rubrics = Rubric.find_by_sql(['SELECT * FROM get_catalogue_root_rubricator(?, ?, ?)', current_region.id, max_level, stat_field])
rubrics_lvl1 = {}
rubrics_lvl2 = []
rubrics.each do |r|
if r.cached_level == 1
rubrics_lvl1[r.id] = r
elsif r.cached_level == 2
unless rubrics_lvl1[r.parent_id].nil?
r.parent_rubric = rubrics_lvl1[r.parent_id] # запоминаем родительскую рубрику
r.descendants_rubrics = [] # создаем задел под рубрики 3-го уровня
r.rows_count_in_current_region = r.current_region_stats
r.rows_count_in_total = current_region.default? ? nil : r.default_region_stats
rubrics_lvl2 << r
end
else
if rubrics_lvl2.last.id == r.parent_id && !rubrics_lvl2.last.descendants_rubrics.nil?
rubrics_lvl2[rubrics_lvl2.length - 1].descendants_rubrics << r
end
end
end
return rubrics_lvl2
end
def rubric
@rubric ||= (params[:path].nil? || params[:path].length == 0 ? Rubric.root : Rubric.with_path(params[:path]).first)
end
def try_rubric_with_old_url
self.http_headers_section = :without_rows
rubric = Rubric.with_old_path(params[:path]).first
if !rubric.nil?
return redirect_to( url_for({:overwrite_params => {:path => rubric.path}}) , :status => 301)
else
return not_found
end
end
def page
@page ||= params[:page] || 1
end
def industry
@industry ||= Industry.with_path(params[:path]).first(:conditions => {:link_to => nil})
end
def firms_query_conditions
conditions = {
:industries => industry.id,
:show_portal => 1
}
conditions[:regions] = current_region.id if !current_region.default?
if !params[:letter].nil? && params[:letter].instance_of?(String)
if params[:letter] == '0-9'
conditions[:first_letter_ord] = ('0'.ord..'9'.ord).to_a
elsif params[:letter].mb_chars.length == 1
params[:letter] = params[:letter].mb_chars.downcase
params[:letter] = 'е' if params[:letter] == 'ё'
conditions[:first_letter_ord] = params[:letter].mb_chars.ord
end
end
return conditions
end
def title
key = @page_title_key ? @page_title_key : 'title'
{:key => "#{@page_title_section}.#{key}",
:values => title_header_descr_values
}
end
def header
{:key => "#{@page_title_section}.h1",
:values => title_header_descr_values}
end
def description
{:key => "#{@page_title_section}.description",
:values => title_header_descr_values}
end
def title_header_descr_values
{:REGION => current_region.name,
:REGION_GENITIVE => current_region.name_genitive,
:RUBRIC => params[:action] == "firms" ? industry.title : (rubric.is_normativka? ? "#{rubric.prefix_normativka} #{rubric.title}" : rubric.title),
:SYNONYM => !rubric.nil? && !rubric.root? ? rubric.synonym : '',
:QUERY => params[:q]
}
end
def load_linked_objects_for_rows!(rows)
# 1. companies
companies_ids = rows.map(&:company_id)
# load predl count for companies
predl_count = PriceListRow.fast_facet('', :company_id, :with => {:company_id => companies_ids, :is_demand => false})
# load including first address, representative users and cities
companies_fields = ['id', 'name', 'packet', 'has_email']
companies = Company.find(companies_ids, :select => companies_fields.join(', '), :include => [:representative, {:main_address => {:city => :city_type}}])
companies_hash = {}
companies.each do |c|
c.predl_count = predl_count[c.id] || 0
companies_hash[c.id] = c
end
# first addresses in region
unless current_region.default?
first_addresses = CompanyRegionCommercial.find(
:all,
:conditions => {:company_id => companies_ids, :region_id => current_region.id},
:include => {:address => {:city => :city_type}}
)
first_addresses.each do |a|
next if companies_hash[a.company_id].nil?
companies_hash[a.company_id].computed_first_address = a.address
end
end
products_ids = []
rows.each_index do |i|
rows[i].company = companies_hash[rows[i].company_id]
products_ids << rows[i].id if rows[i].is_a?(Product)
end
# load images for products
if products_ids.length > 0
images = Image.find(:all,
:select => 'id, subject_type, subject_id, img_file_name',
:conditions => {:subject_type => 'Product', :subject_id => products_ids},
:order => "position DESC")
images_hash = {}
images.each do |img|
images_hash[img.subject_id.to_i] = img
end
rows.each_index do |i|
if rows[i].is_a?(Product) && images_hash[rows[i].id.to_i]
rows[i].first_image = images_hash[rows[i].id.to_i]
end
end
end
rows
end
def load_companies_by_ids(companies_ids)
unless companies_ids.blank?
companies = Company.find(companies_ids, :include => [:company_logo])
# load predl count for companies
predl_count = PriceListRow.fast_facet('', :company_id, :with => {:company_id => companies_ids, :is_demand => false})
companies_hash = {}
if companies.is_a?(Company)
companies.predl_count = predl_count[companies.id]
companies_hash[companies.id] = companies
else
companies.each do |c|
c.predl_count = predl_count[c.id]
companies_hash[c.id] = c
end
end
res = []
companies_ids.each do |id|
res << companies_hash[id]
end
else
res = []
end
def res.sph_result=(r)
@sph = r
end
def res.total_pages
@sph.total_pages
end
def res.current_page
@sph.current_page
end
def res.next_page
@sph.next_page
end
def res.previous_page
@sph.previous_page
end
def res.total_entries
@sph.total_entries
end
res.sph_result = companies_ids
res
end
def http_headers_opts
now = Time.now
opts = {:config_scope => self.http_headers_section.to_s}
if self.http_headers_section == :with_rows
# Last-Modified - каждый час
opts[:headers] = {'Last-Modified' => Time.local(now.year, now.month, now.day, now.hour, 0, 1)}
end
if self.http_headers_section == :without_rows
# Last-Modified - 00:00:01 текущего дня
opts[:headers] = {'Last-Modified' => Time.local(now.year, now.month, now.day, 0, 0, 1)}
end
opts
end
helper_method :rubric
helper_method :page
helper_method :industry
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment