juno-report 0.0.5

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.
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: []