meta_reports 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (111) hide show
  1. checksums.yaml +7 -0
  2. data/Guardfile +15 -0
  3. data/LICENSE +20 -0
  4. data/README.md +146 -0
  5. data/Rakefile +29 -0
  6. data/app/assets/images/meta_reports/print.png +0 -0
  7. data/app/assets/images/meta_reports/spreadsheet.png +0 -0
  8. data/app/assets/javascripts/meta_reports/reports.js +2 -0
  9. data/app/controllers/meta_reports/application_controller.rb +4 -0
  10. data/app/controllers/meta_reports/reports_controller.rb +91 -0
  11. data/app/helpers/meta_reports/reports_helper.rb +140 -0
  12. data/app/models/meta_reports/base.rb +90 -0
  13. data/app/models/meta_reports/data.rb +34 -0
  14. data/app/models/meta_reports/table.rb +80 -0
  15. data/config/routes.rb +9 -0
  16. data/db/migrate/20130801071213_create_meta_reports_reports.rb +17 -0
  17. data/lib/generators/meta_reports/install_generator.rb +40 -0
  18. data/lib/generators/meta_reports/templates/models/report.rb +30 -0
  19. data/lib/generators/meta_reports/templates/views/_form.html.erb +45 -0
  20. data/lib/generators/meta_reports/templates/views/edit.html.erb +6 -0
  21. data/lib/generators/meta_reports/templates/views/forms/_form_example.html.erb +1 -0
  22. data/lib/generators/meta_reports/templates/views/forms/form.html.erb +17 -0
  23. data/lib/generators/meta_reports/templates/views/index.html.erb +36 -0
  24. data/lib/generators/meta_reports/templates/views/new.html.erb +5 -0
  25. data/lib/generators/meta_reports/templates/views/templates/_default.html.erb +26 -0
  26. data/lib/generators/meta_reports/templates/views/templates/_default_footer.pdf.prawn +12 -0
  27. data/lib/generators/meta_reports/templates/views/templates/_default_header.pdf.prawn +14 -0
  28. data/lib/generators/meta_reports/templates/views/templates/_default_header.xlsx.axlsx +20 -0
  29. data/lib/generators/meta_reports/templates/views/templates/_default_table.html.erb +24 -0
  30. data/lib/generators/meta_reports/templates/views/templates/_default_table.pdf.prawn +29 -0
  31. data/lib/generators/meta_reports/templates/views/templates/default.html.erb +1 -0
  32. data/lib/generators/meta_reports/templates/views/templates/default.pdf.prawn +26 -0
  33. data/lib/generators/meta_reports/templates/views/templates/default.xlsx.axlsx +43 -0
  34. data/lib/meta_reports.rb +4 -0
  35. data/lib/meta_reports/engine.rb +15 -0
  36. data/lib/meta_reports/version.rb +3 -0
  37. data/lib/tasks/meta_reports_tasks.rake +4 -0
  38. data/spec/dummy/README.rdoc +261 -0
  39. data/spec/dummy/Rakefile +7 -0
  40. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  41. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  42. data/spec/dummy/app/controllers/application_controller.rb +3 -0
  43. data/spec/dummy/app/controllers/home_controller.rb +4 -0
  44. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  45. data/spec/dummy/app/models/meta_reports/report.rb +30 -0
  46. data/spec/dummy/app/views/home/index.html.erb +4 -0
  47. data/spec/dummy/app/views/layouts/application.html.erb +16 -0
  48. data/spec/dummy/app/views/meta_reports/reports/_form.html.erb +45 -0
  49. data/spec/dummy/app/views/meta_reports/reports/edit.html.erb +6 -0
  50. data/spec/dummy/app/views/meta_reports/reports/forms/_form_moo.html.erb +1 -0
  51. data/spec/dummy/app/views/meta_reports/reports/forms/form.html.erb +17 -0
  52. data/spec/dummy/app/views/meta_reports/reports/index.html.erb +36 -0
  53. data/spec/dummy/app/views/meta_reports/reports/new.html.erb +5 -0
  54. data/spec/dummy/app/views/meta_reports/reports/templates/_default.html.erb +26 -0
  55. data/spec/dummy/app/views/meta_reports/reports/templates/_default_footer.pdf.prawn +12 -0
  56. data/spec/dummy/app/views/meta_reports/reports/templates/_default_header.pdf.prawn +14 -0
  57. data/spec/dummy/app/views/meta_reports/reports/templates/_default_header.xlsx.axlsx +20 -0
  58. data/spec/dummy/app/views/meta_reports/reports/templates/_default_table.html.erb +24 -0
  59. data/spec/dummy/app/views/meta_reports/reports/templates/_default_table.pdf.prawn +29 -0
  60. data/spec/dummy/app/views/meta_reports/reports/templates/default.html.erb +1 -0
  61. data/spec/dummy/app/views/meta_reports/reports/templates/default.pdf.prawn +26 -0
  62. data/spec/dummy/app/views/meta_reports/reports/templates/default.xlsx.axlsx +43 -0
  63. data/spec/dummy/config.ru +4 -0
  64. data/spec/dummy/config/application.rb +65 -0
  65. data/spec/dummy/config/boot.rb +10 -0
  66. data/spec/dummy/config/database.yml +25 -0
  67. data/spec/dummy/config/environment.rb +5 -0
  68. data/spec/dummy/config/environments/development.rb +37 -0
  69. data/spec/dummy/config/environments/production.rb +67 -0
  70. data/spec/dummy/config/environments/test.rb +37 -0
  71. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  72. data/spec/dummy/config/initializers/inflections.rb +15 -0
  73. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  74. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  75. data/spec/dummy/config/initializers/session_store.rb +8 -0
  76. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  77. data/spec/dummy/config/locales/en.yml +5 -0
  78. data/spec/dummy/config/routes.rb +4 -0
  79. data/spec/dummy/config/routes_empty.rb +3 -0
  80. data/spec/dummy/config/routes_original.rb +4 -0
  81. data/spec/dummy/db/development.sqlite3 +0 -0
  82. data/spec/dummy/db/schema.rb +31 -0
  83. data/spec/dummy/log/development.log +22317 -0
  84. data/spec/dummy/public/404.html +26 -0
  85. data/spec/dummy/public/422.html +26 -0
  86. data/spec/dummy/public/500.html +25 -0
  87. data/spec/dummy/public/favicon.ico +0 -0
  88. data/spec/dummy/script/rails +6 -0
  89. data/spec/dummy/tmp/cache/assets/C9B/140/sprockets%2F805babf865ce32228222420a522c7b36 +0 -0
  90. data/spec/dummy/tmp/cache/assets/CBD/2B0/sprockets%2F9e22e937dd267c81a146665f15471b8e +0 -0
  91. data/spec/dummy/tmp/cache/assets/CD0/810/sprockets%2Fe858c95fa595e319dac0065d49982967 +0 -0
  92. data/spec/dummy/tmp/cache/assets/CD0/AC0/sprockets%2F1d341d7a2fc1328567d4b23e0809b2e2 +0 -0
  93. data/spec/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
  94. data/spec/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
  95. data/spec/dummy/tmp/cache/assets/D3D/EB0/sprockets%2F2d47bd3108d9abbb12c0497e36d9674d +0 -0
  96. data/spec/dummy/tmp/cache/assets/D40/8F0/sprockets%2F290aea2004dfecfc76f42e48970f1484 +0 -0
  97. data/spec/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
  98. data/spec/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
  99. data/spec/dummy/tmp/cache/assets/D61/310/sprockets%2Fc168b1c9be3e38ac1c8403a3074b5b8c +0 -0
  100. data/spec/dummy/tmp/cache/assets/D74/AE0/sprockets%2F9ad0425db5cfa16a9426f7b1a7958d7d +0 -0
  101. data/spec/dummy/tmp/cache/assets/D98/270/sprockets%2F0b7ba158ff62bbbb378d6bea80680c63 +0 -0
  102. data/spec/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
  103. data/spec/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
  104. data/spec/dummy/tmp/cache/assets/E5A/EF0/sprockets%2Fb0d5af721ea37c98fd4bccd8e1e5c6ab +0 -0
  105. data/spec/dummy/tmp/pids/server.pid +1 -0
  106. data/spec/features/dummy_spec.rb +42 -0
  107. data/spec/generators/install_spec.rb +51 -0
  108. data/spec/models/data_spec.rb +45 -0
  109. data/spec/models/table_spec.rb +78 -0
  110. data/spec/spec_helper.rb +41 -0
  111. metadata +454 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 047dacfc577bc3d983838e553a621b90ea01155e
4
+ data.tar.gz: 1340266ae16c7c7895102590da7d679bf5aee3c1
5
+ SHA512:
6
+ metadata.gz: db88d50eded3305cae337775669a4ee8c7be2d3fc611d66446916e398e940be3021983db449f4531caacb28fde590da4d795bdaa887ba2d9353f654e43b92ea7
7
+ data.tar.gz: 814b4bfed9dd99f40e8b053ecdb896555594d45ee14b2c39d8b904c345866ee1d141b0127ea8b9f3c3ff77bf07bcc7a55c278eb1eaa5c57538d40fff740425b5
@@ -0,0 +1,15 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard 'rspec', :version => 2, zeus: false, parallel: false, all_on_start: false, all_after_pass: false do
5
+ watch(%r{^spec/.+_spec\.rb$})
6
+ watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
7
+ watch(%r{^app/models/meta_reports/(.+)\.rb$}) { |m| "spec/models/#{m[1]}_spec.rb" }
8
+ watch(%r{^app/controllers/meta_reports/(.+)_(controller)\.rb$}) { |m| "spec/#{m[2]}s/#{m[1]}_#{m[2]}_spec.rb" }
9
+ watch('lib/generators/meta_reports/install_generator.rb') { "spec/generators/install_spec.rb" }
10
+ watch('spec/dummy/app/controllers/application_controller.rb') { "spec/controllers" }
11
+ # dummy app
12
+ watch(%r{^spec/dummy/app/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
13
+ watch(%r{^spec/dummy/app/(.*)(\.erb|\.haml)$}) { |m| "spec/#{m[1]}#{m[2]}_spec.rb" }
14
+ watch(%r{^spec/dummy/app/views/(.+)/.*\.(erb|haml)$}) { |m| "spec/requests/#{m[1]}_spec.rb" }
15
+ end
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2013 YOURNAME
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,146 @@
1
+ #MetaReports
2
+ **A rails report engine**
3
+
4
+ ##Description
5
+
6
+ **MetaReports** is a [Rails](https://github.com/rails/rails) engine for reports. It provides a common metadata structure that can be exported in any desired format. If your report fits within the metadata convention you do not even need a template. However, it is very easy to create reports specific templates also.
7
+
8
+ MetaReports exports to HTML, PDF, and XLSX formats. [More are to come](#todo).
9
+
10
+ ---
11
+
12
+ ##Provides
13
+
14
+ - An ActiveRecord and other data models, a controller, and some generic views.
15
+ - Default views for all formats, that expect a title, subtitle, description, and one or more tables of data.
16
+ - Use css classes for easy styling
17
+
18
+ ##Philosophy
19
+
20
+ MetaReports is avowedly fat model. It is also ActiveRecord based. This could change if a better way makes sense.
21
+
22
+ - **Fat model:** All reports are class methods in the MetaReports::Report class. This allows one to generate reports in various contexts without creating an instance (e.g. a mailer.) The reports themselves are meant to be pure data without formatting, except for class names, and html cell content if that is needed.
23
+ - **ActiveRecord:** Right now a database record is required in addition to the class method. So far this is for convenience in listing available reports and handling permissions. Someday, the code for a report might also be stored in a database, or an abstract description of a report with a web based query builder could be implemented.
24
+ - **Non ActiveRecord:** A non ActiveRecord implementation and install generator will be implemented.
25
+ - **That pesky formatting:** The class names / html content may broken out into helpers or a decorator pattern or something else in the future. It is difficult to think of a useful generic way to specify HTML content (e.g. an HTML link within a paragraph of text) outside of the report method itself. A reports controller already breaks strict REST ideology (where does a report belong that combines 5 models?) and unnecessary work for an ideology does not help create a useful tool.
26
+
27
+ ##Usage
28
+
29
+ ###Installation
30
+
31
+ Add meta_reports your Gemfile:
32
+
33
+ ```ruby
34
+ gem 'meta_reports'
35
+ ```
36
+
37
+ Run the `bundle` command to install it.
38
+
39
+ Now run the generator:
40
+
41
+ rails generate meta_reports:install
42
+
43
+ This copies over the meta_reports migration, model, views, and controller:
44
+
45
+ - `db/migrate/<number>_create_meta_reports_reports.rb`
46
+ - `app/models/meta_reports/report.rb`
47
+ - `app/controllers/meta_reports/reports_controller.rb`
48
+ - `app/views/meta_reports/reports/*`
49
+
50
+ Run the migration:
51
+
52
+ rake db:migrate
53
+
54
+ Add authentication/authorization to the reports controller if desired.
55
+
56
+ ###Writing a report
57
+
58
+ - Write the data method using a static method in the `app/models/meta_reports/report.rb` model. The method should accept the params hash as its single argument. It should return the data in the form of a MetaReports::Data object or a hash.
59
+ - Create a new report record using the reports page. The name must match the data method name.
60
+ - If not using the default templates, write your own templates.
61
+
62
+ ###MetaData
63
+
64
+ The key component of MetaReports is the metadata format. This allows you to write a data method once and export it to any supported format. If you follow convention, the default templates will work out of the box.
65
+
66
+ - **Data:** A MetaReports::Data instance, which is a thinly wrapped hash. Returned by each report method. Methods:
67
+ - **title:** The report title.
68
+ - **subtitle:** The report subtitle, displayed just below the title.
69
+ - **description:** A description, usually displayed in paragraph form between the subtitle and tables of data.
70
+ - **tables:** A hash, where each key is the table title and the value is the data for each table (can be nil).
71
+ - **template:** Specify a template if you are not using the default template.
72
+ - **page_orientation:** :landscape or :portrait. Used on PDF and XLSX formats.
73
+ - **page_margin:** The page margin in pixels (72/inch), in single number or four value array format (top, right, bottom, left.) Used on PDF and XLSX formats. Specify XLSX header/footer margins by specifying a 5th and 6th value respectively.
74
+ - **page_size:** The page size. Used on the PDF format. See the [Prawn documentation](http://prawn.majesticseacreature.com/docs/0.11.1/Prawn/Document/PageGeometry.html).
75
+
76
+ - **Table:** A MetaReports::Table instance, which is a thinly wrapped two dimensional array of cells.
77
+ - **options:** The options for the whole table. If you are using a plain array, this hash must be the last item in the table.
78
+ - **column_widths:** Column widths hash, used only on Prawn PDF output.
79
+ - **font_size:** Font size for content. Used on PDF and XLSX output.
80
+ - **row_classes:** A hash with keys specifying row number (0 first), and values being a string of classes.
81
+ - **table_header:** Defaults to true. First row in the table is a header row. Causes the row to be repeated on Prawn PDF tables if it breaks to another page.
82
+
83
+ - **Cell:** A cell is either a single value, or a hash specifying options:
84
+ - **content:** The default content.
85
+ - **html:** Special content for the HTML report. Used to provide links and other markup.
86
+ - **class:** The class for this content. Used to specify color, alignment, style. For HTML, classes are directly added to the td tags and you are expected to provide appropriate CSS.
87
+ - **left, center, right:** A class of left/center/right or ending with such values will align the content. It is expected you will provide the HTML styles.
88
+ - **bold, strong:** A class of bold or strong will make the content bold.
89
+ - **image:** Specify an image. Only used on PDF output.
90
+
91
+ ###Examples
92
+
93
+ Here is a simple example. See the [example class](spec/dummy/app/models/meta_reports/report.rb) for more.
94
+
95
+ ```ruby
96
+ def self.moo(params)
97
+ MetaReports::Data.new do |d|
98
+ d.title = 'Le Moo'
99
+ d.subtitle = 'Ahem'
100
+ d.tables["The Big Moo"] = MetaReports::Table.new do |t|
101
+ t << ['Number', 'Title', 'Hey']
102
+ t << [1, 'Ode to Moo', 'Ow']
103
+ t << [2, 'Odious Moo', 'Eww']
104
+ t << [3, "#{params[:moo_type]} Moo", 'No Way!']
105
+ t << [3, 'Format', {content: "PDF/XLSX", html: "<span>HTML</span>", class: 'attention'}]
106
+ end
107
+ end
108
+ end
109
+ ```
110
+
111
+ ###Colors
112
+
113
+ There is currently an imperfect implementation of shared colors. You will define your colors by name in the MetaReports::Report class in the COLORS hash constant. If a table row contains a corresponding class name it will have that color in HTML, PDF, and XLSX format. Currently it is only applied in the PDF format. HTML is not far away. It is also intended to implement a means of specifying cell background and text color.
114
+
115
+ ```ruby
116
+ COLORS = {
117
+ even: 'efefef',
118
+ odd: 'ffffff',
119
+ attention: 'ff9999 !important',
120
+ }
121
+ ```
122
+
123
+ Note that you can specify `!important` and it will be reproduced in the HTML style.
124
+
125
+ For HTML, necessary styles will either be injected into the HTML output, or a rake task will be created that will generate an appropriate css file to be included in the layout. I have the latter solution working in a test app, but it is not working as a generic rake task.
126
+
127
+ ##TODO
128
+
129
+ - Common colors: This needs a common color mechanism, where all outputs that support color can have the same row / cell / text color. Any input on this is appreciated.
130
+ - More formats (e.g. csv, json, text)
131
+ - Direct to email / print (using IPP) / fax
132
+ - Improved metadata conventions
133
+
134
+ ##Changelog
135
+
136
+ - **0.1.0:** (9/29/13) Initial release
137
+
138
+ ##Development
139
+
140
+ Fork the project on [github](https://github.com/straydogstudio/meta_reports 'straydogstudio / MetaReports on Github'), edit away, and pull.
141
+
142
+ ### Rspec, and generator testing
143
+
144
+ ##Authors, License and Stuff
145
+
146
+ Code by [Noel Peden](http://straydogstudio.com) and released under [MIT license](http://www.opensource.org/licenses/mit-license.php).
@@ -0,0 +1,29 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'MetaReports'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
24
+ load 'rails/tasks/engine.rake'
25
+
26
+
27
+
28
+ Bundler::GemHelper.install_tasks
29
+
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,4 @@
1
+ module MetaReports
2
+ class ApplicationController < ::ApplicationController
3
+ end
4
+ end
@@ -0,0 +1,91 @@
1
+ require_dependency "meta_reports/application_controller"
2
+
3
+ module MetaReports
4
+ class ReportsController < ApplicationController
5
+ # remember to add authentication/authorization. E.g:
6
+ # before_filter :require_user
7
+ # load_and_authorize_resource
8
+
9
+ def index
10
+ @reports = Report.order("meta_reports_reports.title") || []
11
+ end
12
+
13
+ def show
14
+ if params[:id].to_s =~ /^\d+$/
15
+ _report = Report.find(params[:id])
16
+ elsif Report.respond_to?(params[:id])
17
+ _report = Report.find_by_name(params[:id])
18
+ else
19
+ redirect_to root_url, notice: 'That report does not exist'
20
+ return
21
+ end
22
+ @report = _report.run(params)
23
+ template = {template: "meta_reports/reports/templates/" + (@report[:template] || "default") }
24
+
25
+ respond_to do |format|
26
+ format.html { render template }
27
+ format.pdf { render template }
28
+ format.xlsx { render template }
29
+ end
30
+ _report.view
31
+ end
32
+
33
+ def new
34
+ @report = Report.new
35
+ end
36
+
37
+ def edit
38
+ @report = Report.find params[:id]
39
+ end
40
+
41
+ def create
42
+ @report = Report.new(params[:report])
43
+ if @report.save
44
+ flash[:notice] = 'Report was successfully created.'
45
+ redirect_to(edit_report_path(@report))
46
+ else
47
+ render action: "new"
48
+ end
49
+ end
50
+
51
+ def update
52
+ @report = Report.find params[:id]
53
+ if @report.update_attributes(params[:meta_report])
54
+ flash[:notice] = 'Report was successfully updated.'
55
+ redirect_to(edit_report_path(@report))
56
+ else
57
+ format.html { render action: "edit" }
58
+ end
59
+ end
60
+
61
+ def destroy
62
+ @report = Report.find params[:id]
63
+ @report.destroy
64
+ flash[:notice] = 'Report was successfully deleted.'
65
+
66
+ redirect_to root_url
67
+ end
68
+
69
+ def file
70
+ dir = params[:dir].to_sym
71
+ path = Report::FILE_DIRS[dir] + params[:file].gsub(/\/../,'')
72
+ if File.exists?(path)
73
+ send_file path, type: "application/pdf", x_sendfile: true, disposition: 'inline'
74
+ else
75
+ puts "file doesn't exist: #{path}"
76
+ end
77
+ end
78
+
79
+ def form
80
+ if params[:id].to_s =~ /^\d+$/
81
+ @report = Report.find(params[:id])
82
+ elsif Report.respond_to?(params[:id])
83
+ @report = Report.find_by_name(params[:id])
84
+ else
85
+ redirect_to reports_url, notice: 'That report does not exist'
86
+ return
87
+ end
88
+ render "meta_reports/reports/forms/form"
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,140 @@
1
+ module MetaReports
2
+ module ReportsHelper
3
+ def convert_margins_to_xlsx(margins)
4
+ margins = [*margins].compact.map {|val| val/72.0}
5
+ page_margins = {}
6
+ unless margins.blank?
7
+ len = margins.length
8
+ [:top, :right, :bottom, :left].each_with_index { |dir, i| page_margins[dir] = margins[i%len] }
9
+ if len == 6
10
+ page_margins[:header] = margins[5]
11
+ page_margins[:footer] = margins[6]
12
+ end
13
+ end
14
+ page_margins
15
+ end
16
+
17
+ def html_cell(cell, tag = :td)
18
+ if cell.is_a? Hash
19
+ tags = cell.reject {|k,v| k == :content || k == :html}
20
+ tags[:class] ||= 'textcenter'
21
+ content_tag tag, (cell[:html] || cell[:content]).to_s.html_safe, tags
22
+ elsif cell.is_a? Array
23
+ else
24
+ content_tag tag, cell, :class => 'textcenter'
25
+ end
26
+ end
27
+
28
+ def prep_pdf_table(table, styling)
29
+ if table.is_a?(Array)
30
+ opts = table.last.is_a?(Hash) && table.pop || {}
31
+ data = table
32
+ else
33
+ data = table.to_a
34
+ opts = table.options
35
+ end
36
+ styling[:column_widths] = opts[:column_widths] if opts[:column_widths]
37
+ row_classes = opts[:row_classes] || {}
38
+ row_colors = {}
39
+ row_classes.each do |i, klass|
40
+ if color = MetaReports::Report.color(klass, i)
41
+ row_colors[i] = color
42
+ end
43
+ end
44
+ styling[:row_colors] = row_colors
45
+ data.each_index do |i|
46
+ data[i].each_index do |j|
47
+ if data[i][j].is_a? Hash
48
+ [:html, :title, :id].each {|sym| data[i][j].delete(sym)}
49
+ _class = data[i][j].delete(:class)
50
+ [:right, :left, :center].each do |sym|
51
+ set_style(styling, sym, i, j) if _class =~ /\b#{sym}\b|[^a-z]#{sym}/i
52
+ end
53
+ if _class =~ /\bbold\b|\bstrong\b/
54
+ set_style(styling, :bold, i, j)
55
+ end
56
+ unless data[i][j][:image]
57
+ data[i][j][:content] = data[i][j][:content].to_s unless data[i][j][:content].is_a? String
58
+ end
59
+ end
60
+ end
61
+ end
62
+ data
63
+ end
64
+
65
+ def prep_xlsx_table(table, styling)
66
+ data = table.to_a
67
+ data.each_index do |i|
68
+ data[i].each_index do |j|
69
+ if data[i][j].nil?
70
+ data[i][j] = ''
71
+ elsif data[i][j].is_a? Hash
72
+ _class = data[i][j][:class]
73
+ [:right, :left, :center].each do |sym|
74
+ set_style(styling, sym, i, j) if _class =~ /\b#{sym}\b|[^a-z]#{sym}/i
75
+ end
76
+ if _class =~ /\bbold\b|\bstrong\b/
77
+ set_style(styling, :bold, i, j)
78
+ end
79
+ data[i][j] = data[i][j][:content].to_s
80
+ end
81
+ end
82
+ end
83
+ data
84
+ end
85
+
86
+ def report_link(report, title = report.title)
87
+ if report.direct
88
+ content_tag :span do
89
+ links = []
90
+ if report.format? :html
91
+ links << link_to(title, meta_reports.short_show_path(report), target: '_blank')
92
+ elsif report.format? :pdf
93
+ links << link_to(title, meta_reports.short_show_path(report, format: :pdf), target: '_blank')
94
+ elsif report.format? :xlsx
95
+ links << link_to(title, meta_reports.short_show_path(report, format: :xlsx), target: '_blank')
96
+ end
97
+ if report.format? :pdf
98
+ links << link_to(image_tag('meta_reports/print.png'), meta_reports.short_show_path(report, format: :pdf), target: '_blank')
99
+ end
100
+ if report.format? :xlsx
101
+ links << link_to(image_tag('meta_reports/spreadsheet.png'), meta_reports.short_show_path(report, format: :xlsx), target: '_blank')
102
+ end
103
+ links.join(' ').html_safe
104
+ end
105
+ else
106
+ content_tag :span do
107
+ link_to title, meta_reports.short_form_path(report)
108
+ end
109
+ end
110
+ end
111
+
112
+ def report_alt_links(report, params)
113
+ links = []
114
+ if report.format? :pdf
115
+ links << link_to(image_tag('meta_reports/print.png'), params.merge({:format => :pdf}), :target => '_blank')
116
+ end
117
+ if report.format? :xlsx
118
+ links << link_to(image_tag('meta_reports/spreadsheet.png'), params.merge({:format => :xlsx}), :target => '_blank')
119
+ end
120
+ links.join(' ').html_safe
121
+ end
122
+
123
+ def set_style(styling, style, row, col)
124
+ styling[style] ||= []
125
+ styling[style] << [row,col]
126
+ end
127
+
128
+ def to_xls_col(column)
129
+ index = column.to_i.abs
130
+ chars = []
131
+ while index >= 26 do
132
+ chars << ((index % 26) + 65).chr
133
+ index = (index / 26).to_i - 1
134
+ end
135
+ chars << (index + 65).chr
136
+ chars.reverse.join
137
+ end
138
+
139
+ end
140
+ end