prawn_report 1.9.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. checksums.yaml +7 -0
  2. data/app/controllers/ac_filter_defs_controller.rb +17 -0
  3. data/app/controllers/custom_generate_report_controller.rb +18 -0
  4. data/app/controllers/generate_report_controller.rb +24 -0
  5. data/app/controllers/report_templates_controller.rb +40 -0
  6. data/app/models/ac_filter.rb +15 -0
  7. data/app/models/ac_filter_def.rb +38 -0
  8. data/app/models/ac_filter_option.rb +5 -0
  9. data/app/models/report_template.rb +22 -0
  10. data/lib/ac_filters_utils.rb +187 -0
  11. data/lib/active_record_helpers.rb +218 -0
  12. data/lib/bands/band.rb +23 -0
  13. data/lib/bands/footer_band.rb +7 -0
  14. data/lib/bands/header_band.rb +9 -0
  15. data/lib/bands/summary_band.rb +7 -0
  16. data/lib/custom_report_controller.rb +48 -0
  17. data/lib/generators/prawn_report/install/install_generator.rb +16 -0
  18. data/lib/generators/prawn_report/install/templates/20120108210141_create_prawn_report_catalogs.rb +14 -0
  19. data/lib/generators/prawn_report/install/templates/20120124012653_add_filter_defs.rb +35 -0
  20. data/lib/generators/prawn_report/install/templates/20120209231821_add_filters_to_reports.rb +13 -0
  21. data/lib/generators/prawn_report/install/templates/20120222021437_add_order_to_filter_def.rb +9 -0
  22. data/lib/generators/prawn_report/install/templates/20120222025632_add_select_sql.rb +9 -0
  23. data/lib/generators/prawn_report/install/templates/20120222030526_create_ac_filter_joins.rb +12 -0
  24. data/lib/generators/prawn_report/install/templates/20120222122507_add_serialization_params_to_report.rb +9 -0
  25. data/lib/generators/prawn_report/install/templates/20120222134101_create_ac_filter_includes.rb +12 -0
  26. data/lib/generators/prawn_report/install/templates/20120222150029_change_includes_and_joins_to_hash.rb +21 -0
  27. data/lib/generators/prawn_report/install/templates/20120229134810_add_group_to_filter_def.rb +9 -0
  28. data/lib/generators/prawn_report/install/templates/20120229194434_add_system_criteria_to_ac_filter.rb +9 -0
  29. data/lib/generators/prawn_report/install/templates/20120301063031_change_select_sql.rb +11 -0
  30. data/lib/generators/prawn_report/install/templates/20120303104431_change_filled_criteria_unfilled_criteria.rb +15 -0
  31. data/lib/generators/prawn_report/install/templates/20120316162712_add_filled_criteria_to_options.rb +9 -0
  32. data/lib/generators/prawn_report/install/templates/20120323124446_add_fields_to_filter.rb +17 -0
  33. data/lib/generators/prawn_report/install/templates/20130122101313_add_sql_query_to_ac_filter_def.rb +5 -0
  34. data/lib/generators/prawn_report/install/templates/20131107172133_add_excluir_to_report_template.rb +9 -0
  35. data/lib/prawn_report.rb +21 -0
  36. data/lib/prawn_report/engine.rb +9 -0
  37. data/lib/prawn_report/version.rb +3 -0
  38. data/lib/prawn_report_seeds.rb +46 -0
  39. data/lib/report.rb +190 -0
  40. data/lib/report_helpers.rb +82 -0
  41. data/lib/report_info.rb +27 -0
  42. data/repo/bands/footers/footer_001.rb +20 -0
  43. data/repo/bands/headers/header_001.rb +61 -0
  44. data/repo/bands/headers/header_002.rb +31 -0
  45. data/repo/reports/column_group.rb +58 -0
  46. data/repo/reports/listing.rb +144 -0
  47. data/repo/reports/simple_listing.rb +130 -0
  48. metadata +93 -0
@@ -0,0 +1,190 @@
1
+ #coding: utf-8
2
+
3
+ require 'prawn'
4
+
5
+ require File.expand_path(File.dirname(__FILE__) + "/report_helpers")
6
+ require File.expand_path(File.dirname(__FILE__) + "/report_info")
7
+
8
+ # This is the module for all classes in the prawn_report gem
9
+ module PrawnReport
10
+ unless defined? DEFAULT_REPORT_PARAMS
11
+ DEFAULT_REPORT_PARAMS = {:page_size => 'A4', :margin => [20, 20, 20, 20],
12
+ :page_layout => :portrait}
13
+
14
+ LABEL_SIZE = 6
15
+ TEXT_SIZE = 10
16
+
17
+ SECTION_SPACING = LABEL_SIZE + 4
18
+
19
+ LINE_WIDTH = 0.3
20
+
21
+ DEFAULT_FONT = 'Times-Roman'
22
+
23
+ TEXT_BOX_RADIUS = 2
24
+ TEXT_BOX_HEIGTH = 20
25
+ end
26
+
27
+ # Report is the base class for all reports, it encapsulates all logic for rendering
28
+ # report parts.
29
+ class Report
30
+ attr_reader :pdf, :data, :max_width, :max_height, :totals, :group_totals
31
+ attr_accessor :header_class, :header_other_pages_class, :x, :report_params,
32
+ :running_totals
33
+
34
+ def initialize(report_params)
35
+ @report_params = DEFAULT_REPORT_PARAMS.merge(report_params || {})
36
+ @running_totals = @report_params.delete(:running_totals) || []
37
+ @num_pages = 1
38
+
39
+ @pdf = Prawn::Document.new(@report_params)
40
+
41
+ @pdf.font(DEFAULT_FONT)
42
+ @pdf.line_width = LINE_WIDTH
43
+
44
+ if @report_params[:page_size].is_a?(String)
45
+ if @report_params[:page_layout] == :portrait
46
+ w, h = *Prawn::Document::PageGeometry::SIZES[@report_params[:page_size]]
47
+ else
48
+ h, w = *Prawn::Document::PageGeometry::SIZES[@report_params[:page_size]]
49
+ end
50
+ else
51
+ w, h = @report_params[:page_size]
52
+ end
53
+ @x = 0
54
+ @y = @max_height = h - (@report_params[:margin][0] + @report_params[:margin][2])
55
+ @max_width = w - (@report_params[:margin][1] + @report_params[:margin][3])
56
+
57
+ @footer_size = 0
58
+ @pdf.move_cursor_to(max_height - @report_params[:margin][2])
59
+
60
+ @header_class = @header_other_pages_class = @summary_band_class = @footer_class = nil
61
+ @totals = {}
62
+ @group_totals = {}
63
+
64
+ initialize_running_totals
65
+ end
66
+
67
+ def params
68
+ @report_params
69
+ end
70
+
71
+ def draw(data)
72
+ @data = data
73
+
74
+ draw_header_first_page
75
+ draw_internal
76
+ draw_summary
77
+ draw_footer
78
+
79
+ second_pass
80
+
81
+ @pdf.close_and_stroke
82
+ @pdf.render
83
+ end
84
+
85
+ def new_page(print_titles = true)
86
+ draw_footer
87
+
88
+ @num_pages += 1
89
+ @pdf.start_new_page
90
+ @x = 0
91
+ @pdf.move_down(@report_params[:margin][0])
92
+
93
+ draw_header_other_pages
94
+ end
95
+
96
+ def fill_color(color)
97
+ @pdf.fill_color color
98
+ @pdf.fill_rectangle [x,y], max_width, 15
99
+ @pdf.fill_color '000000'
100
+ end
101
+
102
+ protected
103
+
104
+ def draw_header_first_page
105
+ draw_header(@header_class)
106
+ end
107
+
108
+ def draw_header_other_pages
109
+ draw_header(@header_other_pages_class || @header_class)
110
+ end
111
+
112
+ def draw_header(klass)
113
+ if klass
114
+ header = klass.new(self)
115
+ header.draw
116
+ @pdf.y = @max_height - header.height
117
+ @x = 0
118
+ end
119
+ end
120
+
121
+ def draw_footer
122
+ if @footer_class
123
+ footer = @footer_class.new(self)
124
+ @pdf.move_cursor_to(@footer_class.height)
125
+ footer.draw
126
+ end
127
+ end
128
+
129
+ def draw_summary
130
+ if @summary_class
131
+ summary = @summary_class.new(self)
132
+ summary.draw
133
+ end
134
+ end
135
+
136
+ def draw_group_summary
137
+ if @report_params[:group] && @report_params[:group][:summary_class]
138
+ summary = @report_params[:group][:summary_class].new(self)
139
+ summary.draw
140
+ end
141
+ end
142
+
143
+ def draw_group_header
144
+ if @report_params[:group][:header_class]
145
+ header = @report_params[:group][:header_class].new(self)
146
+ header.draw
147
+ end
148
+ end
149
+
150
+ def second_pass
151
+
152
+ end
153
+
154
+ def run_totals(data_row)
155
+ @running_totals.each do |rt|
156
+ vl = get_raw_field_value(data_row, rt)
157
+ vl = (vl.is_a? (String) ? vl.to_f : vl)
158
+ @totals[rt] = (@totals[rt] || 0) + (vl == '' ? 0 : vl)
159
+ @group_totals[rt] = (@group_totals[rt] || 0) + (vl == '' ? 0 : vl)
160
+ end
161
+ end
162
+
163
+ def initialize_running_totals
164
+ @running_totals.each do |rt|
165
+ @totals[rt] = 0
166
+ @group_totals[rt] = 0
167
+ end
168
+ end
169
+
170
+ def reset_group_totals
171
+ @running_totals.each do |rt|
172
+ @group_totals[rt] = 0
173
+ end
174
+ end
175
+
176
+ def reset_totals
177
+ @running_totals.each do |rt|
178
+ @totals[rt] = 0
179
+ end
180
+ end
181
+
182
+ def get_raw_field_value(row, column_name)
183
+ c = row
184
+ column_name.split('.').each {|n| c = c[n] if c}
185
+ c.nil? ? '' : c
186
+ end
187
+
188
+ end
189
+ end
190
+
@@ -0,0 +1,82 @@
1
+ # coding: utf-8
2
+
3
+ module PrawnReport
4
+ class Report
5
+
6
+ def box(width, height, options = {})
7
+ @pdf.rounded_rectangle([0, y], width, height, TEXT_BOX_RADIUS)
8
+ end
9
+
10
+ def text_box_with_box(label, text, width, height = nil, options = {})
11
+ @pdf.rounded_rectangle([@x, y], width, height || TEXT_BOX_HEIGTH, TEXT_BOX_RADIUS)
12
+ @pdf.text_box(label, :size => LABEL_SIZE, :at => [@x + 2, y - 2], :width => width - 2,
13
+ :height => LABEL_SIZE, :valign => :top)
14
+ h_text = height.nil? ? TEXT_SIZE : height - LABEL_SIZE - 4
15
+ @pdf.text_box(text || '', { :size => TEXT_SIZE, :at => [@x + 2, y - LABEL_SIZE - 4],
16
+ :width => width - 2, :height => h_text, :valign => :top }.merge(options))
17
+ @x += width
18
+ end
19
+
20
+ def text(text, width, options = {})
21
+ font_size = options[:font_size] || TEXT_SIZE
22
+ @pdf.text_box(text, :size => font_size, :style => options[:style], :at => [@x, y - 4],
23
+ :width => width, :height => font_size,
24
+ :valign => (options[:valign] || :top),
25
+ :align => (options[:align] || :left)
26
+ )
27
+ @x = @x + width
28
+ end
29
+
30
+ def horizontal_line(x_ini = 0, x_end = @max_width)
31
+ @pdf.stroke do
32
+ @pdf.horizontal_line(x_ini, x_end, :at => y)
33
+ end
34
+ end
35
+
36
+ def y
37
+ @pdf.y
38
+ end
39
+
40
+ def y=(y)
41
+ @pdf.y = y
42
+ end
43
+
44
+ def space(width)
45
+ @x += width
46
+ end
47
+
48
+ def line_break(size = TEXT_SIZE)
49
+ @x = 0
50
+ @pdf.move_down(@pdf.height_of('A', :size => size) + 2)
51
+ end
52
+
53
+ def format(value, formatter, options = {})
54
+ if !value.nil? && value != ''
55
+ if (formatter == :currency)
56
+ if value < 0
57
+ '-'+((value.to_i*-1).to_s.reverse.gsub(/...(?=.)/,'\&.').reverse) + ',' + ('%02d' % ((value.abs * 100).round % 100))
58
+ else
59
+ (value.to_i.to_s.reverse.gsub(/...(?=.)/,'\&.').reverse) + ',' + ('%02d' % ((value * 100).round % 100))
60
+ end
61
+ elsif (formatter == :date)
62
+ value.to_time.strftime('%d/%m/%Y')
63
+ elsif (formatter == :timezone_date)
64
+ tz = Time.zone.parse(value)
65
+ tz.nil? ? '' : tz.strftime('%d/%m/%Y')
66
+ elsif (formatter == :function)
67
+ send(options[:formatter_function].to_s, value)
68
+ else
69
+ value.to_s
70
+ end
71
+ else
72
+ ''
73
+ end
74
+ end
75
+
76
+ def draw_graph(g, params)
77
+ data = StringIO.new(g.to_blob)
78
+ @pdf.image(data, params)
79
+ end
80
+
81
+ end
82
+ end
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+
3
+ require 'date'
4
+
5
+ module PrawnReport
6
+ class Report
7
+
8
+ attr_accessor :force_today_as
9
+
10
+ def fits?(h)
11
+ (y - footer_size - h - @report_params[:margin][2]) >= 0
12
+ end
13
+
14
+ def header_size
15
+ @header ? @header_class.height : 0
16
+ end
17
+
18
+ def footer_size
19
+ @footer_class ? @footer_class.height : 0
20
+ end
21
+
22
+ def today
23
+ @force_today_as ? @force_today_as : Date.today
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,20 @@
1
+ #coding: utf-8
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + "/../../../lib/bands/footer_band")
4
+
5
+ module PrawnReport
6
+
7
+ class Footer001 < FooterBand
8
+
9
+ def internal_draw
10
+ report.horizontal_line
11
+ report.x = 0
12
+ end
13
+
14
+ def self.height
15
+ 10
16
+ end
17
+
18
+ end
19
+
20
+ end
@@ -0,0 +1,61 @@
1
+ #coding: utf-8
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + "/../../../lib/bands/header_band")
4
+
5
+ module PrawnReport
6
+
7
+ #This header renders:
8
+ #
9
+ #* Company name based on a property at the root of data named +company_name+ left aligned
10
+ # font size 16.
11
+ #* Data de emissão dated today right aligned font size 12
12
+ #* Report name based on a parameter named +report_name+ setted in the report
13
+ #* A list of filters read from *report.params[:filters]*. Each filter is printed in one
14
+ # line. *params[:filters]* must be an array of arrays where the inner arrays must be
15
+ # tuples of two elements, the first one being the title and second one being the value of the
16
+ # filter. If value is present the title is concatenated with ':'
17
+ class Header001 < HeaderBand
18
+
19
+ def initialize(report, params = {})
20
+ super(report, params)
21
+ @filter_size = 0
22
+ end
23
+
24
+ def internal_draw
25
+ report.text(report.data['company_name'], 300, :style => :bold, :font_size => 16)
26
+ txt_emissao = 'Data de emissão: ' + report.today.strftime('%d/%m/%Y')
27
+ length = report.pdf.width_of(txt_emissao, :size => 12)
28
+ report.x = report.max_width - length
29
+ report.text(txt_emissao, length, :font_size => 12,
30
+ :valign => :bottom, :align => :right)
31
+ report.line_break(16)
32
+ report.text(report.params[:report_name], report.max_width, :font_size => 13,
33
+ :align => :center)
34
+ report.line_break(13)
35
+ draw_filters if report.params[:filters]
36
+ report.horizontal_line
37
+ end
38
+
39
+ def draw_filters
40
+ report.params[:filters].each do |param|
41
+ title = param[0]
42
+ if param[1].to_s != ''
43
+ title = title + ':'
44
+ end
45
+ report.text(title, 2 + report.pdf.width_of(title, :size => 10), :font_size => 10)
46
+ report.text(param[1], 2 + report.pdf.width_of(param[1], :size => 10), :font_size => 10)
47
+ report.x = 0
48
+ size = report.pdf.height_of(param[1], :size => 10)
49
+ size = 10 if size < 10
50
+ report.pdf.move_down(size + 2)
51
+ @filter_size += size + 2
52
+ end
53
+ end
54
+
55
+ def height
56
+ 45 + @filter_size
57
+ end
58
+
59
+ end
60
+
61
+ end
@@ -0,0 +1,31 @@
1
+ #coding: utf-8
2
+
3
+ require File.expand_path(File.dirname(__FILE__) + "/../../../lib/bands/header_band")
4
+
5
+ module PrawnReport
6
+ #This is a minimalist header intended to render the company name and report name in additional
7
+ #pages of a report.
8
+ #
9
+ #This header renders:
10
+ #
11
+ #* Company name based on a property at the root of data named +company_name+ left aligned
12
+ # font size 12.
13
+ #* Report name based on a parameter named +report_name+ setted in the report
14
+ class Header002 < HeaderBand
15
+
16
+ def internal_draw
17
+ report.x = 0
18
+ report.text(report.data['company_name'], 300, :font_size => 12)
19
+ report.x = 0
20
+ report.text(report.params[:report_name], report.max_width, :font_size => 12, :align => :right)
21
+ report.line_break(12)
22
+ report.horizontal_line
23
+ end
24
+
25
+ def height
26
+ 20
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -0,0 +1,58 @@
1
+ module PrawnReport
2
+ class NoGroupingFieldProvided < Exception; end
3
+ class NoGroupingValueFieldProvided < Exception; end
4
+ class NoGroupingContextFieldProvided < Exception; end
5
+
6
+ class ColumnGroup < Listing
7
+ attr_accessor :grouping_field
8
+ attr_accessor :grouping_context_field
9
+ attr_accessor :grouping_value_field
10
+
11
+ def new_page(print_titles = true)
12
+ draw_column_titles if print_titles
13
+ end
14
+
15
+ def before_draw_lines
16
+ super
17
+ draw_column_titles
18
+ end
19
+
20
+ def initialize(report_params = {})
21
+ super(report_params)
22
+ raise NoGroupingFieldProvided unless report_params[:grouping_field]
23
+ raise NoGroupingValueFieldProvided unless report_params[:grouping_value_field]
24
+ raise NoGroupingContextFieldProvided unless report_params[:grouping_context_field]
25
+ @grouping_field = report_params[:grouping_field]
26
+ @grouping_value_field = report_params[:grouping_value_field]
27
+ @grouping_context_field = report_params[:grouping_context_field]
28
+ end
29
+
30
+ def draw(data)
31
+ data = traverse_data(data)
32
+ super(data)
33
+ end
34
+
35
+ protected
36
+
37
+ def traverse_data(data)
38
+ new_data = []
39
+ last_value = nil
40
+ new_row = nil
41
+ old_data = data[@detail_name]
42
+ old_data.each do |row|
43
+ if row[@grouping_field] != last_value then
44
+ new_data << new_row unless new_row.nil?
45
+ last_value = row[@grouping_field]
46
+ new_row = {}
47
+ row.each_pair {|k,v| new_row[k] = v}
48
+ end
49
+ new_row[@grouping_context_field.to_s + '_' + row[@grouping_context_field].to_s] = row[@grouping_value_field]
50
+ end
51
+ new_data << new_row unless new_row.nil?
52
+ data[@detail_name]=new_data
53
+ data
54
+ end
55
+
56
+
57
+ end
58
+ end