sniffer_plugin_myprofile_controller.rb 5.14 KB
class SnifferPluginMyprofileController < MyProfileController

  include SnifferPlugin::Helper
  helper SnifferPlugin::Helper
  helper CmsHelper

  def edit
    if request.post?
      if @profile.update params[:profile_data]
        session[:notice] = _('Consumer interests updated')
      end
    end
  end

  def product_category_search
    query = params[:q] || params[:term]

    @categories = find_by_contents(:categories, @profile, environment.product_categories, query, {per_page: 10, page: 1})[:results]

    autocomplete = params.has_key?(:term)
    render json: @categories.map { |i| autocomplete ? {value: i.id, label: i.name} : {id: i.id, name: i.name} }
  end

  def product_category_add
    product_category = environment.categories.find params[:id]
    response = { productCategory: {
        :id   => product_category.id
      }
    }
    response[:enterprises] = product_category.sniffer_plugin_enterprises.enabled.visible.map do |enterprise|
      profile_data = filter_visible_attr_profile(enterprise)
      profile_data[:balloonUrl] = url_for controller: :sniffer_plugin_myprofile, action: :map_balloon, id: enterprise[:id], escape: false
      profile_data[:sniffer_plugin_distance] = Noosfero::GeoRef.dist(@profile.lat, @profile.lng, enterprise.lat, enterprise.lng)
      profile_data[:suppliersProducts] = filter_visible_attr_suppliers_products(
        enterprise.products.sniffer_plugin_products_from_category(product_category)
      )
      profile_data[:consumersProducts] = []
      profile_data
    end
    render text: response.to_json
  end

  def search
    @no_design_blocks = true

    suppliers_products = @profile.sniffer_suppliers_products
    consumers_products = @profile.sniffer_consumers_products

    profiles_of_interest = fetch_profiles(suppliers_products + consumers_products)

    suppliers_categories = suppliers_products.collect(&:product_category)
    consumers_categories = consumers_products.collect(&:product_category)

    @categories = categories_with_interest_type(suppliers_categories, consumers_categories)

    suppliers = suppliers_products.group_by{ |p| target_profile_id(p) }
    consumers = consumers_products.group_by{ |p| target_profile_id(p) }

    @profiles_data = {}
    suppliers.each do |id, products|
      @profiles_data[id] = {
        profile: profiles_of_interest[id],
        suppliers_products: products,
        consumers_products: []
      }
    end
    consumers.each do |id, products|
      @profiles_data[id] ||= { profile: profiles_of_interest[id] }
      @profiles_data[id][:suppliers_products] ||= []
      @profiles_data[id][:consumers_products] = products
    end
  end

  def map_balloon
    @profile_of_interest = Profile.find params[:id]
    @categories = @profile_of_interest.categories

    suppliers_products = params[:suppliersProducts].blank? ? [] : params[:suppliersProducts].values
    consumers_products = params[:consumersProducts].blank? ? [] : params[:consumersProducts].values
    @empty = suppliers_products.empty? && consumers_products.empty?
    @has_both = !suppliers_products.blank? && !consumers_products.blank?

    @suppliers = build_products(suppliers_products).values.first
    @consumers = build_products(consumers_products).values.first

    render layout: false
  end

  def my_map_balloon
    @categories = @profile.categories
    render layout: false
  end

  protected

  def fetch_profiles(products)
    profiles = Profile.where id: products.map{ |p| target_profile_id p }
    profiles_by_id = {}
    profiles.each do |p|
      p.sniffer_plugin_distance = Noosfero::GeoRef.dist(@profile.lat, @profile.lng, p.lat, p.lng)
      profiles_by_id[p.id] ||= p
    end
    profiles_by_id
  end

  def build_products(data)
    id_products, id_knowledges = {}, {}

    results = {}
    return results if data.blank?

    grab_id = proc{ |field| data.map{ |h| h[field].to_i }.uniq }

    id_profiles = fetch_profiles(data)

    products = Product.where(id: grab_id.call('id')).includes(:enterprise, :product_category)
    products.each{ |p| id_products[p.id] ||= p }
    knowledges = Article.where(id: grab_id.call('knowledge_id'))
    knowledges.each{ |k| id_knowledges[k.id] ||= k}

    data.each do |attributes|
      profile = id_profiles[target_profile_id(attributes)]

      results[profile.id] ||= []
      results[profile.id] << {
        partial: attributes['view'],
        product: id_products[attributes['id'].to_i],
        knowledge: id_knowledges[attributes['knowledge_id'].to_i]
      }
    end
    results
  end

  def target_profile_id(product)
    p = product.is_a?(Hash) ? product : product.attributes
    p.delete_if { |key, value| value.blank? }
    (p['consumer_profile_id'] || p['supplier_profile_id'] || p['profile_id']).to_i
  end

  def categories_with_interest_type(suppliers_categories, consumers_categories)
    (suppliers_categories + consumers_categories).sort_by(&:name).uniq.map do |category|
      c = {id: category.id, name: category.name}
      if suppliers_categories.include?(category) && consumers_categories.include?(category)
        c[:interest_type] = :both
      else
        suppliers_categories.include?(category) ? c[:interest_type] = :supplier : c[:interest_type] = :consumer
      end
      c
    end
  end

end