Class: Effective::Report

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
app/models/effective/report.rb

Constant Summary collapse

DATATYPES =
[:boolean, :date, :decimal, :integer, :price, :string, :belongs_to, :belongs_to_polymorphic, :has_many, :has_one]
OPERATIONS =

Arel::Predications.instance_methods

[:eq, :not_eq, :matches, :does_not_match, :starts_with, :ends_with, :gt, :gteq, :lt, :lteq, :sql]

Instance Method Summary collapse

Instance Method Details

#col(name, atts = {}) ⇒ Object

Find or build



63
64
65
66
67
68
# File 'app/models/effective/report.rb', line 63

def col(name, atts = {})
  atts[:name] ||= name.to_sym
  atts[:as] ||= reportable_attributes[name]

  report_columns.find { |col| atts.all? { |k, v| col.send(k).to_s == v.to_s } } || report_columns.build(atts)
end

#collectionObject

The klass to base the collection from



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
# File 'app/models/effective/report.rb', line 175

def collection
  collection = reportable.all

  # Apply Scopes
  report_scopes.each do |scope|
    collection = scope.apply_scope(collection)
  end

  # Apply Includes
  report_columns.select(&:as_associated?).each do |column|
    collection = collection.includes(column.name)
  end

  # Apply Filters
  report_columns.select(&:filter?).each do |column|
    collection = Resource.new(collection).search(column.name, column.value, operation: column.operation)
  end

  collection
end

#duplicateObject



156
157
158
159
160
161
162
163
164
165
166
167
168
# File 'app/models/effective/report.rb', line 156

def duplicate
  Effective::Report.new(attributes.except('id', 'updated_at', 'created_at')).tap do |report|
    report.title = title + ' (Copy)'

    report_columns.each do |report_column|
      report.report_columns.build(report_column.attributes.except('id', 'updated_at', 'created_at'))
    end

    report_scopes.each do |report_scope|
      report.report_scopes.build(report_scope.attributes.except('id', 'updated_at', 'created_at'))
    end
  end
end

#duplicate!Object



170
171
172
# File 'app/models/effective/report.rb', line 170

def duplicate!
  duplicate.tap { |event| event.save! }
end

#email_report_columnObject



83
84
85
# File 'app/models/effective/report.rb', line 83

def email_report_column
  report_columns.find { |column| column.name == 'email' } || report_columns.find { |column| column.name.include?('email') }
end

#filtered_report_columnsObject



79
80
81
# File 'app/models/effective/report.rb', line 79

def filtered_report_columns
  report_columns.select(&:filter?)
end

#notification(atts = {}) ⇒ Object



75
76
77
# File 'app/models/effective/report.rb', line 75

def notification(atts = {})
  notifications.find { |col| atts.all? { |k, v| col.send(k).to_s == v.to_s } } || notifications.build(atts)
end

#reportableObject



58
59
60
# File 'app/models/effective/report.rb', line 58

def reportable
  reportable_class_name.constantize if reportable_class_name.present?
end

#reportable_attributesObject

Used to build the Reports form { id: :integer, archived: :boolean }



95
96
97
98
99
100
101
102
103
104
# File 'app/models/effective/report.rb', line 95

def reportable_attributes
  attributes = Hash((reportable.new.reportable_attributes if reportable))

  attributes.each do |attribute, type|
    raise("#{reportable}.reportable_attributes #{attribute} => #{type || 'nil'} is invalid. Key must be a symbol") unless attribute.kind_of?(Symbol)
    raise("#{reportable}.reportable_attributes :#{attribute} => #{type || 'nil'} is invalid. Value must be one of #{DATATYPES.map { |s| ":#{s}"}.join(', ')}") unless DATATYPES.include?(type)
  end

  attributes
end

#reportable_scopesObject

{ active: nil, inactive: nil, with_first_name: :string, not_in_good_standing: :boolean }



107
108
109
110
111
112
113
114
115
116
117
# File 'app/models/effective/report.rb', line 107

def reportable_scopes
  scopes = Hash((reportable.new.reportable_scopes if reportable))

  scopes.each do |scope, type|
    raise("#{reportable}.reportable_scopes #{scope} => #{type || 'nil'} is invalid. Key must be a symbol") unless scope.kind_of?(Symbol)
    raise("#{reportable}.reportable_scopes :#{scope} => #{type || 'nil'} is invalid. Value must be one of #{DATATYPES.map { |s| ":#{s}"}.join(', ')}") if type.present? && !DATATYPES.include?(type)
    raise("#{reportable} must respond to reportable scope :#{scope}") unless reportable.respond_to?(scope)
  end

  scopes
end

#scope(name, atts = {}) ⇒ Object



70
71
72
73
# File 'app/models/effective/report.rb', line 70

def scope(name, atts = {})
  atts[:name] ||= name.to_sym
  report_scopes.find { |scope| scope.name == name.to_s } || report_scopes.build(atts)
end

#seedsObject

Return a string you can copy and paste into a seeds file



120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'app/models/effective/report.rb', line 120

def seeds
  seeds = [
    "report = Effective::Report.where(title: \"#{title}\", reportable_class_name: \"#{reportable_class_name}\").first_or_initialize",
    ("report.assign_attributes(description: \"#{description}\")" if description.present?),
  ].compact

  seeds += report_columns.map do |column|
    attributes = column.dup.attributes.except('name', 'report_id', 'position', 'as').compact
    attributes.delete('filter') unless attributes['filter']

    if attributes.present?
      attributes = attributes.map { |k, v| "#{k}: #{v.inspect}" }.join(', ')
      "report.col(:#{column.name}, #{attributes})"
    else
      "report.col(:#{column.name})"
    end
  end

  seeds += report_scopes.map do |scope|
    attributes = scope.dup.attributes.except('name', 'report_id', 'position').compact

    if attributes.present?
      attributes = attributes.map { |k, v| "#{k}: #{v.inspect}" }.join(', ')
      "report.scope(:#{scope.name}, #{attributes})"
    else
      "report.scope(:#{scope.name})"
    end
  end

  seeds += [
    "report.save!"
  ]

  seeds.join("\n")
end

#to_sObject



54
55
56
# File 'app/models/effective/report.rb', line 54

def to_s
  title.presence || 'report'
end

#user_report_columnObject



87
88
89
90
91
# File 'app/models/effective/report.rb', line 87

def user_report_column
  report_columns.find { |column| column.name == 'user' } ||
  report_columns.find { |column| column.name == 'owner' } ||
  report_columns.find { |column| column.name.include?('user') }
end