query_report 1.0.23 → 1.0.24

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8c09663de9764af4df12bdbe7da6cecbae1c7ca0
4
- data.tar.gz: b7e286d433248e29f8b078632f8f18ddbde73a57
3
+ metadata.gz: 38e6dd09227f6ad51d81593b879ded5928ab3c27
4
+ data.tar.gz: 72ef9413da84d9e5d0f5f802c5b7dd8e4cd4aba0
5
5
  SHA512:
6
- metadata.gz: 92ea49358da764dbd315424074025e665f933a2e8c4e7cc96fa02af0ad1b31b27bf8f926a097146d6edf85d64c127ab19ffe3cc6d8f993a73e0c245738186156
7
- data.tar.gz: c713b7bb180db57c9a55c612768d86032740152177bd802961241a047098705f11768d3b04bed3f362b307f8a8378b3007aeb7ad9ca15577bf521d435f9e2b0d
6
+ metadata.gz: aad743d74172a389cc058f6354d819b7e1263fcea268bffcecd1c4d3a2928e38c1b02563cc8f75ff2571472300ee7a2709669cd42cc02d7a8963534599a611d3
7
+ data.tar.gz: 8d5c76e9381b2df6a078f133a82d02ac459f483e93c7afa9281011a58eceb4e50fe800e33ce5add15a104a01c7f2e3da909188ae2fe5e55431c22044f1ecb209
data/README.md CHANGED
@@ -2,14 +2,50 @@
2
2
 
3
3
  [![Build Status](https://api.travis-ci.org/ashrafuzzaman/query_report.png?branch=master)](http://travis-ci.org/ashrafuzzaman/query_report)
4
4
  [![Gem Version](https://badge.fury.io/rb/query_report.png)](http://badge.fury.io/rb/query_report)
5
-
6
- Query report is a reporting tool, which does the following:
7
-
8
- * Generate paginated HTML view with filters, defined columns with sorting
9
- * Generate PDF, CSV, JSON
10
- * Provide feature to define re usable custom filter
11
-
12
- As built in filter I have used [ransack](https://github.com/ernie/ransack) and pagination with [kaminari](https://github.com/amatsuda/kaminari)
5
+ [![Code Climate](https://codeclimate.com/github/ashrafuzzaman/query_report.png)](https://codeclimate.com/github/ashrafuzzaman/query_report)
6
+ [![Code coverage](https://codeclimate.com/github/ashrafuzzaman/query_report/coverage.png)](https://codeclimate.com/github/ashrafuzzaman/query_report)
7
+
8
+ ###Write the action with a simple DSL and get a report with PDF and CSV export, gorgeous charts, out of box filters, with I18n support, etc...
9
+
10
+ Create a report in Rails
11
+ ------------------------
12
+
13
+ You would have to do the following tasks to create a report in rails,
14
+
15
+ - Create a route
16
+ - Create an action with following logic
17
+ - Logic for filters
18
+ - Logic for pagination
19
+ - Create a view
20
+ - Write code to show HTML
21
+ - Write code to generate Graph
22
+ - Generate PDF with prawn pdf and graph
23
+ - Logic to send that PDF file as email
24
+
25
+ Create a report with query report
26
+ ---------------------------------
27
+
28
+ - Create a route
29
+ - Create an action with following logic
30
+ - ~~Logic for filters~~
31
+ - ~~Logic for pagination~~
32
+ - ~~Create a view~~
33
+ - ~~Write code to show HTML~~
34
+ - ~~Write code to generate Graph~~
35
+ - ~~Generate PDF with prawn pdf and graph~~
36
+ - ~~Logic to send that PDF file as email~~
37
+
38
+ For email, you have to implement the popup once.
39
+
40
+ Features
41
+ --------
42
+
43
+ - Allow to use and reuse filters using [ransack](https://github.com/activerecord-hackery/ransack), and also with custom query
44
+ - Paginates [kaminari](https://github.com/amatsuda/kaminari)
45
+ - Supports ajax out of box
46
+ - Exports to PDF [prawn](https://github.com/prawnpdf/prawn), csv, json
47
+ - Supports to send report pdf as email
48
+ - Supports I18N
13
49
 
14
50
  For a demo see [here](http://query-report-demo.herokuapp.com)
15
51
 
@@ -45,8 +81,8 @@ class InvoicesController < ApplicationController
45
81
  column :title do |invoice|
46
82
  link_to invoice.title, invoice
47
83
  end
48
- column :total_paid
49
- column :total_charged
84
+ column :total_paid, show_total: true
85
+ column :total_charged, show_total: true
50
86
  column :paid
51
87
  end
52
88
  end
@@ -2,7 +2,7 @@
2
2
  <table class="<%= QueryReport.config.record_table_class %>" cellpadding="0" cellspacing="0">
3
3
  <thead>
4
4
  <% report.columns.each do |column| %>
5
- <th><%= column.sortable? ? sort_link(report.search, column.name, params, remote: @remote) : column.humanize %></th>
5
+ <th><%= column.sortable? ? sort_link(report.search, column.sort_link_attribute, column.humanize, params, remote: @remote) : column.humanize %></th>
6
6
  <% end %>
7
7
  </thead>
8
8
 
@@ -8,14 +8,52 @@ module QueryReport
8
8
  attr_accessor :columns
9
9
 
10
10
  # Creates a filter and adds to the filters
11
- # Params:
12
- # +column+:: the column on which the filter is done on
13
- # +options+:: Options can have the following,
14
- # options[:type] => date | text | whatever
15
- # options[:comp] => the comparators used for ransack search, [:gteq, :lteq]
16
- # options[:show_total] => set true to calculate total for that column
17
- # options[:only_on_web] => the column will appear on the web and not appear in PDF or csv if set to true
18
- # options[:rowspan] => the rows with same values in the same column will span if set to true
11
+ # @param name the column on which the filter is done on
12
+ # @option options [Symbol] :type date | text | whatever
13
+ # @option options [String] :as The title of the column, by default it fetches from the I18n column translation, Model.human_attribute_name(column_name)
14
+ # @option options [Boolean] :show_total set true to calculate total for that column. It will render the total in the footer.
15
+ # @option options [Boolean] :only_on_web the column will appear on the web and not appear in PDF, CSV or JSON if set to true
16
+ # @option options [Boolean] :sortable if set to true then sorts on that column, but if the sorting has to be on a joint table then you have to specify the column on which the sorting will happen
17
+ # @option options :rowspan the rows with same values in the same column will span if set to true
18
+ #
19
+ # @example Row span
20
+ # column :invoiced_to_name, rowspan: true
21
+ # column :invoice_title
22
+ # column :invoice_date, rowspan: :invoiced_to_name
23
+ # ┌───────────┬────────────┬─────────────────┐
24
+ # │ Name │ Invoice │ Invoiced on │
25
+ # ├───────────┼────────────┼─────────────────┤
26
+ # │ │ Invoice1 │ │
27
+ # │ Jitu ├────────────┤ 2-2-2014 │
28
+ # │ │ Invoice2 │ │
29
+ # ├───────────┼────────────┼─────────────────┤
30
+ # │ Setu │ Invoice3 │ 2-2-2014 │
31
+ # └───────────┴────────────┴─────────────────┘
32
+ #
33
+ # @example Show total
34
+ # column :invoiced_to_name, rowspan: true
35
+ # column :invoice_title
36
+ # column :total_charged, show_total: true
37
+ # ┌───────────┬────────────┬─────────────────┐
38
+ # │ Name │ Invoice │ Total charge │
39
+ # ├───────────┼────────────┼─────────────────┤
40
+ # │ │ Invoice1 │ 100 │
41
+ # │ Jitu ├────────────┼─────────────────┤
42
+ # │ │ Invoice2 │ 120 │
43
+ # ├───────────┼────────────┼─────────────────┤
44
+ # │ Setu │ Invoice3 │ 80 │
45
+ # ├───────────┴────────────┼─────────────────┤
46
+ # │ Total │ 300 │
47
+ # └────────────────────────┴─────────────────┘
48
+ #
49
+ # @example Sorting
50
+ # column :invoice_date, sortable: true
51
+ # column :invoice_to, sortable: 'users.name'
52
+ #
53
+ # If you want to sort a column which is a column of the active record model that the query returns,
54
+ # then just set true to make the column sortable.
55
+ # If the column is from another table then you have to specify the column name.
56
+ #
19
57
  def column(name, options={}, &block)
20
58
  @columns << Column.new(self, name, options, block)
21
59
  end
@@ -59,7 +97,11 @@ module QueryReport
59
97
  end
60
98
 
61
99
  def sortable?
62
- @options[:sortable] == true
100
+ @options[:sortable].present? && @options[:sortable] != false
101
+ end
102
+
103
+ def sort_link_attribute
104
+ @options[:sortable] == true ? name : @options[:sortable]
63
105
  end
64
106
 
65
107
  def rowspan?
@@ -67,12 +109,16 @@ module QueryReport
67
109
  end
68
110
 
69
111
  def rowspan_column_humanized
112
+ return @rowspan_column_humanized if @rowspan_column_humanized
70
113
  rowspan_column_name = @options[:rowspan].kind_of?(Symbol) ? @options[:rowspan] : self.name
71
114
 
72
115
  report.columns.each do |column|
73
- return column.humanize if column.name == rowspan_column_name
116
+ if column.name == rowspan_column_name
117
+ @rowspan_column_humanized = column.humanize
118
+ return @rowspan_column_humanized
119
+ end
74
120
  end
75
- return self.humanize
121
+ @rowspan_column_humanized = self.humanize
76
122
  end
77
123
 
78
124
  def humanize
@@ -104,7 +150,6 @@ module QueryReport
104
150
  end
105
151
  end
106
152
  end
107
-
108
153
  end
109
154
  end
110
155
  end
@@ -10,29 +10,38 @@ module QueryReport
10
10
  module FilterModule
11
11
  attr_accessor :filters, :search
12
12
 
13
- # Creates a filter and adds to the filters
14
- # Params:
15
- # +column+:: the column on which the filter is done on
16
- # +options+:: Options can have the following,
17
- # options[:type] => date | text | whatever
18
- # options[:comp] => the comparators used for ransack search, [:gteq, :lteq]
19
- # options[:manual] => if set to true then that filter will not be applied, only will appear and can be used for custom application
20
- # options[:default] => support default filter value, can be one value or for range filter can be array
13
+ # Creates a filter
14
+ # @param column the column on which the filter is done on, for manual filter the column name can be anything
15
+ # @option options [Symbol] :type date | text | whatever
16
+ # @option options [Array] :comp the comparators used for ransack search, [:gteq, :lteq]
17
+ # @option options [Boolean] :manual if set to true then that filter will not be applied, only will appear and can be used for custom application
18
+ # @option options :default support default filter value, can be one value or for range filter can be array
19
+ #
20
+ # @example Custom type
21
+ # filter :invoiced_to_id, type: :user
22
+ #
23
+ # # In a helper file define method
24
+ # def query_report_user_filter(name, user_id, options={})
25
+ # user = User.find(user_id)
26
+ # concat hidden_field_tag name, user_id, options
27
+ # text_field_tag "#{name}", user.name, class: 'user_search' #implement the filter, it can be autocomplete
28
+ # end
29
+ #
30
+
21
31
  def filter(column, options={}, &block)
22
32
  @filters ||= []
23
33
  @filters << Filter.new(@params, column, options, &block)
24
34
  end
25
35
 
26
- def has_filter?
27
- filters.present?
28
- end
29
-
30
36
  def apply_filters(query, http_params)
31
37
  # apply default filter
32
38
  params = load_default_values_in_param(http_params) #need for ransack filter
33
39
  @search = query.ransack(params[:q])
34
40
  query = @search.result
35
41
 
42
+ #this is to fix a bug from ransack, as for ransack when the sorting is done from a joined table it does not sort by default
43
+ query = query.order(params[:q][:s]) if params[:q][:s]
44
+
36
45
  #apply custom filter
37
46
  @filters.select(&:custom?).each do |filter|
38
47
  ordered_custom_param_values = ordered_param_value_objects(filter)
@@ -42,24 +51,6 @@ module QueryReport
42
51
  query
43
52
  end
44
53
 
45
- def ordered_param_value_objects(filter)
46
- filter.comparators.collect do |comp|
47
- comp.objectified_param_value
48
- end
49
- end
50
-
51
- def load_default_values_in_param(http_params)
52
- params = http_params.clone
53
- params = params.merge(q: {}) unless params[:q]
54
- params = params.merge(custom_search: {}) unless params[:custom_search]
55
- @filters.each do |filter|
56
- filter.comparators.each do |comparator|
57
- params[filter.params_key][comparator.search_key] ||= comparator.param_value
58
- end
59
- end
60
- params
61
- end
62
-
63
54
  class Filter
64
55
  attr_reader :params, :column, :type, :comparators, :block, :options
65
56
 
@@ -120,5 +111,27 @@ module QueryReport
120
111
  end
121
112
  end
122
113
  end
114
+
115
+ def has_filter?
116
+ filters.present?
117
+ end
118
+
119
+ def ordered_param_value_objects(filter)
120
+ filter.comparators.collect do |comp|
121
+ comp.objectified_param_value
122
+ end
123
+ end
124
+
125
+ def load_default_values_in_param(http_params)
126
+ params = http_params.clone
127
+ params = params.merge(q: {}) unless params[:q]
128
+ params = params.merge(custom_search: {}) unless params[:custom_search]
129
+ @filters.each do |filter|
130
+ filter.comparators.each do |comparator|
131
+ params[filter.params_key][comparator.search_key] ||= comparator.param_value
132
+ end
133
+ end
134
+ params
135
+ end
123
136
  end
124
137
  end
@@ -11,12 +11,10 @@ module QueryReport
11
11
  module Helper
12
12
 
13
13
  # Generates the reports
14
- # Params:
15
- # query - The base query that the reporter with start with [filters will be applied on it]
16
- # options - Options for the reports
17
- # :custom_view - by default false, if set to true then the reporter will look for the file to render
18
- # :skip_rendering - by default false, if set to true then the reporter will not render any thing, you will have to implement the rendering
19
- # :per_page - If given then overrides the default kaminari per page option
14
+ # @param query The base query that the reporter with start with [filters will be applied on it]
15
+ # @option options [Integer] :per_page If given then overrides the default kaminari per page option
16
+ # @option options [Boolean] :custom_view by default false, if set to true then the reporter will look for the file to render
17
+ # @option options [Boolean] :skip_rendering by default false, if set to true then the reporter will not render any thing, you will have to implement the rendering
20
18
  def reporter(query, options={}, &block)
21
19
  @report ||= QueryReport::Report.new(params, view_context, options)
22
20
  @report.query = query
@@ -78,7 +76,7 @@ module QueryReport
78
76
  end
79
77
 
80
78
  def send_pdf_email(email, subject, message, file_name, attachment)
81
- @user = current_user
79
+ @user = current_user if defined? current_user
82
80
  to = email.split(',')
83
81
  ReportMailer.send_report(@user, to, subject, message, file_name, attachment).deliver
84
82
  end
@@ -1,3 +1,3 @@
1
1
  module QueryReport
2
- VERSION = "1.0.23"
2
+ VERSION = "1.0.24"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: query_report
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.23
4
+ version: 1.0.24
5
5
  platform: ruby
6
6
  authors:
7
7
  - A.K.M. Ashrafuzzaman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-05-29 00:00:00.000000000 Z
11
+ date: 2014-06-04 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: railties
@@ -252,3 +252,4 @@ signing_key:
252
252
  specification_version: 4
253
253
  summary: Structure you reports
254
254
  test_files: []
255
+ has_rdoc: