category.rb 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071
  1. class Category < ActiveRecord::Base
  2. ##--- Associaciones
  3. has_many :products, -> { where "products.status = 1" }
  4. belongs_to :parent, class_name: "Category"
  5. has_many :children, -> { where "categories.status!= 0" }, class_name: "Category", foreign_key: 'parent_id'
  6. enum status: [:erased, :active, :inactive]
  7. ##--- Llevar registro de Actividad del usuario
  8. audited
  9. ##--- Validaciones previas de guardar
  10. validates :category, presence: { message: "Debe capturar el nombre de la línea de producto." }
  11. ##--- Tipo de vistas / consultas
  12. scope :vigentes, -> { where("status != 0").order("status ASC, category ASC") }
  13. scope :activos, -> { where("status = 1").order("category ASC") }
  14. scope :activos_padre, -> { where("categories.status = 1 AND categories.parent_id = 0").order("categories.category ASC") }
  15. scope :get_parents, -> { where("categories.parent_id = 0 and categories.status != 0").order("categories.category ASC") }
  16. def descendents
  17. self_and_descendents - [self]
  18. end
  19. def self_and_descendents
  20. self.class.tree_for(self)
  21. end
  22. def self.tree_for(instance)
  23. where("#{table_name}.id IN (#{tree_sql_for(instance)})").order("#{table_name}.id")
  24. end
  25. def self.sales_by_category(pointsale_id)
  26. @pointsale = Pointsale.find(pointsale_id)
  27. @category_parents = Category.get_parents
  28. @sales_details = Pointsale.find(pointsale_id).sales_details.includes(:sale).where('sales.status != 1')
  29. puts "PUNTO DE VENTA: #{@pointsale.name}"
  30. puts "CATEGORIAS: #{@category_parents.count}"
  31. puts "TOTAL DE PRODUCTOS VENDIDOS: #{@sales_details.count}"
  32. cats = Hash.new
  33. @category_parents.each do |category|
  34. products_ids = category.children.includes(:products).pluck('products.id')
  35. prods_from_category = @sales_details.where('product_id in (?) ', products_ids).count
  36. percent_of_this_cat = (prods_from_category * 100) / @sales_details.count
  37. # puts "CATEGORIA: #{category.category} #{percent_of_this_cat}%"
  38. cats[category.category.to_s] = percent_of_this_cat unless percent_of_this_cat.zero?
  39. end
  40. cats.sort_by { |_key, value| value }.reverse
  41. end
  42. def self.tree_sql_for(instance)
  43. tree_sql = <<-SQL
  44. WITH RECURSIVE search_tree(id, path) AS (
  45. SELECT id, ARRAY[id]
  46. FROM #{table_name}
  47. WHERE id = #{instance.id}
  48. UNION ALL
  49. SELECT #{table_name}.id, path || #{table_name}.id
  50. FROM search_tree
  51. JOIN #{table_name} ON #{table_name}.parent_id = search_tree.id
  52. WHERE NOT #{table_name}.id = ANY(path)
  53. )
  54. SELECT id FROM search_tree ORDER BY path
  55. SQL
  56. end
  57. before_save do
  58. self.parent_id = 0 if parent_id.nil?
  59. end
  60. end