juno-report 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ tmp
2
+ spec/reports
3
+
4
+ *.gem
5
+ InstalledFiles
6
+ *.rbc
7
+ .config
8
+ rdoc
9
+ test/version_tmp
10
+ lib/bundler/man
11
+ .bundle
12
+ pkg
13
+ coverage
14
+ .yardoc
15
+ junoreport.sublime-project
16
+ junoreport.sublime-workspace
17
+ # YARD artifacts
18
+ test/tmp
19
+ _yardoc
20
+ doc/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in juno-report.gemspec
4
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,14 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ juno-report (0.0.1)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+
10
+ PLATFORMS
11
+ ruby
12
+
13
+ DEPENDENCIES
14
+ juno-report!
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Edson Júnior
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,197 @@
1
+ # Juno Report
2
+
3
+ Cry with Report Generation? Nevermore!
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'juno-report'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install juno-report
18
+
19
+ ## Usage
20
+
21
+ The generating reports is based on a YAML file with all rules, with the fields and their settings, divided by sections.
22
+
23
+ ### Body section
24
+
25
+ Represents the records which will be iterated to report generating
26
+
27
+ ```yaml
28
+ # example.yml
29
+ body:
30
+ settings: {posY: 40, height: 25}
31
+ fields:
32
+ test_field1: [10]
33
+ test_field2: [220]
34
+ test_field3: [430, {column: "Named Test Field 3"}]
35
+ footer:
36
+ label_total: [10, {value: "Total"}]
37
+ totalizer: [220, {behavior: count}]
38
+ test_field3: [430, {behavior: sum}]
39
+ ```
40
+ The [body] section ***must*** have three rules:
41
+
42
+ * `settings`: Defines some configurations for body, like their height and ypos.
43
+ * `fields`: Describes each field of record to be iterated.
44
+ * `footer`: Drawn at the end of all printed records and calculates fields according behavior parameter.
45
+
46
+ Each of these rules receives a array, where the first position is an integer representing the field horizontal position and
47
+ the second position is a hash with some configurations.
48
+
49
+
50
+ ##### Settings
51
+
52
+ * `height`: Set the of each row at report [Integer].
53
+ * `posY`: Relative vertical position of last row at report [Integer].
54
+ * `groups`: Describes which groups will be printed (More bellow) [Array].
55
+
56
+ ##### Fields
57
+
58
+ * `size`: Font size of the field [Integer].
59
+ * `align`: Defines the text alignment for each value [left|center|right].
60
+ * `font`: Supports all font type provided by Prawn gem (See more in http://rubydoc.info/gems/prawn/Prawn/Font/AFM).
61
+ * `style`: Stylistic variations of a font [bold|italic].
62
+ * `value`: Fixed text to be printed [string].
63
+ * `column`: The header are "humanized" automatically, but you can set other value manually [string].
64
+
65
+ ##### Footer
66
+
67
+ * `behavior`: Specify a function to be performed, sending as parameter the fieldname value [string].
68
+ * `label`: Preppends a text to fieldname value specified [string].
69
+ * `value`: Fixed text to be printed (fieldname value will be ignored) [string].
70
+
71
+ With theses configurations already is possible generate a basic report, without groups feature.
72
+ For this we need call the generate method on JunoReport module:
73
+
74
+ ```ruby
75
+ # test.rb
76
+ require 'juno-report'
77
+
78
+ data = [
79
+ {:test_field1 => 'Test Value 1', :test_field2 => "Test Value 2", :test_field3 => 50},
80
+ {:test_field1 => 'Test Value 1', :test_field2 => "Test Value 2", :test_field3 => 7},
81
+ {:test_field1 => 'Test Value 1', :test_field2 => "Test Value 2", :test_field3 => 10},
82
+ {:test_field1 => 'Test Value 1', :test_field2 => "Test Value 2", :test_field3 => 5},
83
+ {:test_field1 => 'Test Value 1', :test_field2 => "Test Value 2", :test_field3 => 2},
84
+ {:test_field1 => 'Test Value 1', :test_field2 => "Test Value 2", :test_field3 => 4},
85
+ {:test_field1 => 'Test Value 1', :test_field2 => "Test Value 2", :test_field3 => 24}
86
+ ]
87
+
88
+ JunoReport::generate(data, :report => 'example')
89
+ ```
90
+
91
+ The first parameter must be a set of hash or objects which represent the report data. And the second parameter is a hash
92
+ with the report settings, that can be:
93
+
94
+ * `report`: The source of all rules. Must be a YAML file [string].
95
+ * `type`: Specify if the report will be writed on the disc or returned to the caller such a stream [:file|:stream]
96
+ * `filename`: Defines the report name which will be writed on disc. If not specified, the default name is "report.pdf" [string].
97
+
98
+ ### Page section
99
+
100
+ You may want to print a title every time that a page is created. You simply insert a [page] section.
101
+
102
+ ```yaml
103
+ # example.yml
104
+ page:
105
+ fields:
106
+ title1: [260, {size: 24, align: center, value: "Test Report"}]
107
+ subtitle1: [260, {size: 20, posY: 20, align: center, value: "Generated by Juno Report"}]
108
+ body:
109
+ settings: {posY: 40, height: 25}
110
+ fields:
111
+ test_field1: [10]
112
+ test_field2: [220]
113
+ test_field3: [430, {column: "Named Test Field 3"}]
114
+ footer:
115
+ label_total: [10, {value: "Total"}]
116
+ totalizer: [220, {behavior: count}]
117
+ test_field3: [430, {behavior: sum}]
118
+ ```
119
+
120
+ ### Groups section
121
+
122
+ For each item in groups parameter at body section you should create a section with same name.
123
+ This section represents the header configurations to every time that the group is printed and behaves like [body] section.
124
+
125
+ ```yaml
126
+ # example.yml
127
+ page:
128
+ fields:
129
+ title1: [260, {size: 24, align: center, value: "Test Report"}]
130
+ subtitle1: [260, {size: 20, posY: 20, align: center, value: "Generated by Juno Report"}]
131
+ body:
132
+ settings: {posY: 40, height: 30, groups: [group_field1, group_field2]}
133
+ fields:
134
+ test_field1: [10]
135
+ test_field2: [220]
136
+ test_field3: [420, {column: "Named Test Field 3"}]
137
+ footer:
138
+ label_total: [10, {value: "Total"}]
139
+ totalizer1: [220, {behavior: count}]
140
+ test_field3: [420, {behavior: sum}]
141
+ group_field1:
142
+ settings: {posY: 30, height: 10}
143
+ fields:
144
+ group_field1: [10, size: 25]
145
+ footer:
146
+ group_field1: [10, {label: "Total "}]
147
+ totalizer1: [220, {behavior: count}]
148
+ test_field3: [420, {behavior: sum}]
149
+ group_field2:
150
+ settings: {posY: 30, height: 25}
151
+ fields:
152
+ group_field2: [10, size: 17]
153
+ footer:
154
+ group_field2: [10, {label: "Total "}]
155
+ totalizer1: [220, {behavior: count}]
156
+ test_field3: [420, {behavior: sum}]
157
+ ```
158
+
159
+ Every time that a "group field" value changes, the group will be printed.
160
+
161
+ ```ruby
162
+ # test.rb
163
+ require 'juno-report'
164
+
165
+ data = [
166
+ {:test_field1 => 'Test Value 1', :test_field2 => "Test Value 1", :test_field3 => 50, :group_field1 => 'Group 1', :group_field2 => 'Subgroup 1'},
167
+ {:test_field1 => 'Test Value 2', :test_field2 => "Test Value 2", :test_field3 => 16, :group_field1 => 'Group 1', :group_field2 => 'Subgroup 1'},
168
+ {:test_field1 => 'Test Value 5', :test_field2 => "Test Value 3", :test_field3 => 7, :group_field1 => 'Group 1', :group_field2 => 'Subgroup 1'},
169
+ {:test_field1 => 'Test Value 3', :test_field2 => "Test Value 9", :test_field3 => 10, :group_field1 => 'Group 1', :group_field2 => 'Subgroup 2'},
170
+ {:test_field1 => 'Test Value 3', :test_field2 => "Test Value 2", :test_field3 => 4, :group_field1 => 'Group 1', :group_field2 => 'Subgroup 2'},
171
+ {:test_field1 => 'Test Value 9', :test_field2 => "Test Value 4", :test_field3 => 10, :group_field1 => 'Group 1', :group_field2 => 'Subgroup 2'},
172
+ {:test_field1 => 'Test Value 7', :test_field2 => "Test Value 5", :test_field3 => 5, :group_field1 => 'Group 1', :group_field2 => 'Subgroup 3'},
173
+ {:test_field1 => 'Test Value 3', :test_field2 => "Test Value 5", :test_field3 => 2, :group_field1 => 'Group 1', :group_field2 => 'Subgroup 3'},
174
+ {:test_field1 => 'Test Value 3', :test_field2 => "Test Value 2", :test_field3 => 27, :group_field1 => 'Group 2', :group_field2 => 'Subgroup 1'},
175
+ {:test_field1 => 'Test Value 3', :test_field2 => "Test Value 5", :test_field3 => 2, :group_field1 => 'Group 2', :group_field2 => 'Subgroup 1'},
176
+ {:test_field1 => 'Test Value 0', :test_field2 => "Test Value 4", :test_field3 => 13, :group_field1 => 'Group 2', :group_field2 => 'Subgroup 1'},
177
+ {:test_field1 => 'Test Value 4', :test_field2 => "Test Value 7", :test_field3 => 7, :group_field1 => 'Group 2', :group_field2 => 'Subgroup 1'},
178
+ {:test_field1 => 'Test Value 1', :test_field2 => "Test Value 3", :test_field3 => 28, :group_field1 => 'Group 2', :group_field2 => 'Subgroup 1'},
179
+ {:test_field1 => 'Test Value 4', :test_field2 => "Test Value 5", :test_field3 => 4, :group_field1 => 'Group 2', :group_field2 => 'Subgroup 2'},
180
+ {:test_field1 => 'Test Value 5', :test_field2 => "Test Value 6", :test_field3 => 24, :group_field1 => 'Group 2', :group_field2 => 'Subgroup 2'}
181
+ ]
182
+
183
+ JunoReport::generate(data, :report => 'example', :filename => 'juno-report.pdf')
184
+ ```
185
+
186
+ ## Contributors
187
+
188
+ 2. Edson Júnior (http://github.com/ebfjunior)
189
+
190
+ ## Contributing
191
+
192
+ 1. Fork it
193
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
194
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
195
+ 4. Push to the branch (`git push origin my-new-feature`)
196
+ 5. Create new Pull Request
197
+
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,21 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require 'juno-report/version'
4
+
5
+ Gem::Specification.new do |gem|
6
+ gem.name = "juno-report"
7
+ gem.version = JunoReport::VERSION
8
+ gem.platform = Gem::Platform::RUBY
9
+ gem.authors = ["Edson Júnior"]
10
+ gem.email = ["ejunior.batista@gmail.com"]
11
+ gem.description = "A simple, but efficient, report genarator yaml based"
12
+ gem.summary = "Juno Reports generates reports with the minimum configuration and effort"
13
+ gem.homepage = "http://github.com/ebfjunior/juno-report"
14
+
15
+ gem.files = `git ls-files`.split("\n")
16
+ gem.executables = gem.files.grep(%r{^bin/}).map { |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ gem.add_dependency "prawml"
21
+ end
@@ -0,0 +1,32 @@
1
+ require "juno-report/version"
2
+ require "juno-report/pdf"
3
+ require "juno-report/pdf/behaviors"
4
+ require "prawml"
5
+
6
+ module JunoReport
7
+ autoload :ReportObject, 'juno-report/report_object'
8
+
9
+ def self.generate(collection, options)
10
+ rules = "#{options[:report]}.yml"
11
+
12
+ defaults = {
13
+ :page_layout => :portrait
14
+ }
15
+
16
+ pdf = Prawml::PDF.new rules, defaults.merge(options)
17
+
18
+ pdf.extend JunoReport::Pdf
19
+ report = pdf.generate(collection)
20
+
21
+ options[:type] ||= :file
22
+
23
+ if options[:type].eql? :file
24
+ report.render_file (options[:filename] || "report.pdf")
25
+ elsif options[:type].eql? :stream
26
+ return report
27
+ else
28
+ raise "Type options must be :file or :stream."
29
+ end
30
+
31
+ end
32
+ end
@@ -0,0 +1,234 @@
1
+ module JunoReport
2
+ module Pdf
3
+
4
+ #Responsible for generate a report, based on rules passed as parameter in Juno::Report::generate.
5
+ #Juno Reports has support groups, just by especifying them at the rules file.
6
+ #Receives a collection as parameter, which should be a Array of records of the report.
7
+ def generate(collection)
8
+ @defaults = {
9
+ :style => :normal,
10
+ :size => 12,
11
+ :align => :left,
12
+ :format => false,
13
+ :font => 'Times-Roman',
14
+ :type => :text,
15
+ :color => '000000',
16
+ :fixed => false
17
+ }
18
+
19
+ get_sections
20
+ set_pos_y
21
+
22
+ collection = [collection] unless collection.is_a?(Array)
23
+ print_section :page unless @sections[:page].nil?
24
+ set_pos_y (@sections[:body][:settings][:posY] || 0)
25
+ @current_groups = {}
26
+ @footers = {}
27
+
28
+ unless @sections[:groups].empty?
29
+ reset_groups_values
30
+ else
31
+ draw_columns
32
+ end
33
+
34
+ initialize_footer_values
35
+ can_print_footer = false
36
+
37
+ collection.each do |record|
38
+ @record = record.is_a?(Hash) ? ReportObject.new(record) : record #Convert the hash on a Object to futurely extend a module
39
+
40
+ headers_to_print, headers_height = calculate_header
41
+
42
+ unless headers_to_print.empty?
43
+ draw_footer headers_to_print, @sections[:groups] if can_print_footer
44
+ if @posY - headers_height < 2*@sections[:body][:settings][:height]
45
+ new_page
46
+ else
47
+ headers_to_print.each { |group| print_section group, @record, true }
48
+ draw_columns
49
+ end
50
+ end
51
+ can_print_footer = true
52
+
53
+ update_footer_values
54
+ print_section :body, @record
55
+ end
56
+
57
+ draw_footer(@sections[:body][:settings][:groups].collect {|group| group.to_sym}, @sections[:groups]) if has_groups?
58
+ draw_footer [:body], @sections
59
+
60
+ @pdf
61
+ end
62
+
63
+ protected
64
+
65
+ #Creates a new page, restarting the vertical position of the pointer.
66
+ #Print the whole header for the current groups and the columns of the report.
67
+ def new_page
68
+ @pdf.start_new_page
69
+ set_pos_y
70
+ print_section :page unless @sections[:page].nil?
71
+ set_pos_y (@sections[:body][:settings][:posY] || 0)
72
+ @current_groups.each do |field, value|
73
+ print_section field.to_sym, @record, true
74
+ end
75
+ draw_columns
76
+ end
77
+
78
+ #Generic function to print a section like :body, :page or the group sections.
79
+ def print_section(section_name, values = nil, group = false)
80
+ section = !group ? @sections[section_name] : @sections[:groups][section_name]
81
+ set_pos_y(section[:settings][:posY] || 0) unless section_name.eql?(:body) || section[:settings].nil?
82
+ new_page if @posY < 30
83
+
84
+ section[:fields].each do |field, settings|
85
+ symbolize! settings[1] unless settings[1].nil?
86
+ set_pos_y settings[1][:posY] unless settings[1].nil? || settings[1][:posY].nil?
87
+ settings = [settings[0], @posY, (@defaults.merge (settings[1] || { }))]
88
+ settings[2][:style] = settings[2][:style].to_sym
89
+ set_options settings[2]
90
+
91
+ value = settings[2][:value].nil? ? (values.respond_to?(field) ? values.send(field) : "") : settings[2][:value]
92
+ draw_text value, settings
93
+ end
94
+ set_pos_y (section[:settings][:height]) unless section[:settings].nil? || section[:settings][:height].nil?
95
+ end
96
+
97
+ #Print a horizontal line with the whole width of the page.
98
+ def draw_line(y)
99
+ width = @options[:page_layout] == :portrait ? 530 : 770
100
+ @pdf.stroke { @pdf.horizontal_line 0, width, :at => y }
101
+ end
102
+
103
+ #Update the pointer vertical position to the specified value or 'zero' if the parameter is nil.
104
+ #Obs: Prawn pointer is decrescent, in other words, the left-top corner position is (0, 750). For
105
+ #semantic purposes, we set the same corner as (0, 0).
106
+ def set_pos_y(posY = nil)
107
+ height = @options[:page_layout] == :portrait ? 750 : 520
108
+ @posY = height if @posY.nil?
109
+ @posY = posY.nil? ? height : @posY - posY
110
+ end
111
+
112
+ #Convert to symbol all hash keys, recursively.
113
+ def symbolize! hash
114
+ hash.symbolize_keys!
115
+ hash.values.select{|v| v.is_a? Hash}.each{|h| symbolize!(h)}
116
+ end
117
+
118
+ #Convert the structure of the rules to facilitate the generating proccess.
119
+ def get_sections
120
+ symbolize! @rules
121
+ raise "[body] section on YAML file is needed to generate the report." if @rules[:body].nil?
122
+ @sections = {:page => @rules[:page], :body => @rules[:body], :groups => {}}
123
+ @sections[:body][:settings][:groups].each { |group| @sections[:groups][group.to_sym] = @rules[group.to_sym] } if has_groups?
124
+ end
125
+
126
+ #@current_groups storages the value for all groups. When a value is changed, the header is printed.
127
+ #This function set nil value for every item in @current_groups if the parameter is not passed. Otherwise,
128
+ #only the forward groups will be cleaned to avoid conflict problems with others groups.
129
+ def reset_groups_values current_group = nil
130
+ groups = @sections[:body][:settings][:groups]
131
+ groups.each_with_index do |group, idx|
132
+ @current_groups[group] = nil if current_group.nil? || groups.index(current_group.to_s) <= idx
133
+ end
134
+ end
135
+
136
+
137
+ #Calculates the headers which must be printed before print the current record.
138
+ #The function also returns the current header height to create a new page if the
139
+ #page remaining space is smaller than (header + a record height)
140
+ def calculate_header
141
+ headers = []
142
+ height = 0
143
+ @current_groups.each do |field, value|
144
+ if @record.send(field) != value
145
+ reset_groups_values field
146
+
147
+ headers << field.to_sym
148
+ height += @sections[:groups][field.to_sym][:settings][:height] + @sections[:groups][field.to_sym][:settings][:posY]
149
+
150
+ @current_groups[field] = @record.send(field)
151
+ end
152
+ end unless @current_groups.empty?
153
+ [headers, height]
154
+ end
155
+
156
+ #Create a structure to calculate the footer values for all groups. Appends the footer body to total values too.
157
+ def initialize_footer_values
158
+ @sections[:body][:settings][:groups].each do |group|
159
+ current_footer = {}
160
+ @sections[:groups][group.to_sym][:footer].each { |field, settings| current_footer[field] = nil } unless @sections[:groups][group.to_sym][:footer].nil?
161
+ @footers[group.to_sym] = current_footer unless current_footer.empty?
162
+ end if has_groups?
163
+ raise "The report must have at least a footer on body section" if @sections[:body][:footer].nil?
164
+ current_footer = {}
165
+ @sections[:body][:footer].each { |field, settings| current_footer[field] = nil }
166
+ @footers[:body] = current_footer unless current_footer.empty?
167
+ end
168
+
169
+ #Call the function that calculates the footer values for all groups and the total body footer, with
170
+ #different source for each
171
+ def update_footer_values
172
+ @sections[:body][:settings][:groups].reverse_each do |group|
173
+ calculate_footer_values group, @sections[:groups][group.to_sym][:footer]
174
+ end if has_groups?
175
+ calculate_footer_values :body, @sections[:body][:footer]
176
+ end
177
+
178
+ #Returns the values to the group passed as parameter. If :behavior setting is used, so a
179
+ #function in [lib/pdf/behaviors.rb] calculates the value of current field, else the report
180
+ #method is called
181
+ def calculate_footer_values group, source
182
+ @footers[group.to_sym].each do |field, value|
183
+ footer_rule = source[field]
184
+ symbolize! footer_rule[1]
185
+ unless footer_rule[1][:behavior].nil?
186
+ @footers[group.to_sym][field] = JunoReport::Pdf::Behaviors.send footer_rule[1][:behavior].to_sym, value, (@record.respond_to?(field) ? @record.send(field) : nil)
187
+ else
188
+ @footers[group.to_sym][field] = footer_rule[1][:value] || (footer_rule[1][:label].to_s + @record.send(field))
189
+ end unless @footers[group.to_sym].nil? || footer_rule[1].nil?
190
+ end
191
+ end
192
+
193
+ #Print the footers according to the groups and source specified
194
+ def draw_footer footers_to_print, source
195
+ footers_to_print.reverse_each do |group|
196
+ draw_line(@posY + @sections[:body][:settings][:height]/2)
197
+ source[group][:footer].each do |field, settings|
198
+ settings = [settings[0], @posY, (@defaults.merge (settings[1] || { }).symbolize_keys!)]
199
+ settings[2][:style] = settings[2][:style].to_sym
200
+ set_options settings[2]
201
+ draw_text @footers[group][field], settings
202
+ end
203
+ draw_line(@posY - @sections[:body][:settings][:height]/4)
204
+ set_pos_y @sections[:body][:settings][:height]
205
+
206
+ reset_footer group
207
+ end
208
+ end
209
+
210
+ #Resets the footer to next groups
211
+ def reset_footer(group); @footers[group].each { |field, value| @footers[group][field] = nil }; end
212
+
213
+ #Based on the Key names of the :body section at the rules, the function draw columns with
214
+ #baselines on the top and bottom of the header.
215
+ def draw_columns
216
+ @sections[:body][:fields].each do |field, settings|
217
+ settings = [settings[0], @posY, (@defaults.merge (settings[1] || { }).symbolize_keys!)]
218
+ settings[2][:style] = settings[2][:style].to_sym
219
+ set_options settings[2]
220
+ draw_line(@posY + @sections[:body][:settings][:height]/2)
221
+ field = settings[2][:column] || field.to_s.split('_').inject('') do |str, part|
222
+ str << part.camelize << " "
223
+ end
224
+ draw_text field, settings
225
+ end
226
+ draw_line(@posY - @sections[:body][:settings][:height]/2)
227
+ set_pos_y @sections[:body][:settings][:height]
228
+ end
229
+
230
+ def has_groups?
231
+ !@sections[:body][:settings][:groups].nil?
232
+ end
233
+ end
234
+ end
@@ -0,0 +1,18 @@
1
+ module JunoReport
2
+ module Pdf
3
+ module Behaviors
4
+ def self.sum old_value, new_value
5
+ value = (old_value.to_f + new_value.to_f).to_s
6
+ (/^[0-9]+(?=\.)/.match value).nil? ? value : value[/^[0-9]+(?=\.)/]
7
+ end
8
+
9
+ def self.substract old_value, new_value
10
+ old_value.to_f - new_value.to_f
11
+ end
12
+
13
+ def self.count old_value, new_value = nil
14
+ old_value.to_i + 1
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,9 @@
1
+ class ReportObject
2
+ def initialize(hash)
3
+ hash.each do |k,v|
4
+ self.instance_variable_set("@#{k}", v)
5
+ self.class.send(:define_method, k, proc{self.instance_variable_get("@#{k}")})
6
+ self.class.send(:define_method, "#{k}=", proc{|v| self.instance_variable_set("@#{k}", v)})
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,3 @@
1
+ module JunoReport
2
+ VERSION = "0.0.5"
3
+ end
metadata ADDED
@@ -0,0 +1,73 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: juno-report
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.5
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Edson Júnior
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-02-22 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: prawml
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ description: A simple, but efficient, report genarator yaml based
31
+ email:
32
+ - ejunior.batista@gmail.com
33
+ executables: []
34
+ extensions: []
35
+ extra_rdoc_files: []
36
+ files:
37
+ - .gitignore
38
+ - Gemfile
39
+ - Gemfile.lock
40
+ - LICENSE.txt
41
+ - README.md
42
+ - Rakefile
43
+ - juno-report.gemspec
44
+ - lib/juno-report.rb
45
+ - lib/juno-report/pdf.rb
46
+ - lib/juno-report/pdf/behaviors.rb
47
+ - lib/juno-report/report_object.rb
48
+ - lib/juno-report/version.rb
49
+ homepage: http://github.com/ebfjunior/juno-report
50
+ licenses: []
51
+ post_install_message:
52
+ rdoc_options: []
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ! '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ none: false
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ requirements: []
68
+ rubyforge_project:
69
+ rubygems_version: 1.8.23
70
+ signing_key:
71
+ specification_version: 3
72
+ summary: Juno Reports generates reports with the minimum configuration and effort
73
+ test_files: []