magic-report 0.7.0 → 0.7.1

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d55f3c2c7537067d5b4e825ec2dae5fb4856243aa436c0fc4a24c411124cf826
4
- data.tar.gz: f6cb0bd78b371f3649a9fd4cd9df00841a56dfacb4e67bed3074c02e796ab6a3
3
+ metadata.gz: 88305b9a5045e8cd60e96f3ebc8f7991726303f6461cd8de483ccbb483dba5f4
4
+ data.tar.gz: fb088083b95b0aeff7ca7fd4e92fa567e2685ff566ee8c6459582ed1e1876e6d
5
5
  SHA512:
6
- metadata.gz: ef278542203ac22032ec90f68d29cda496d224f18ff38c9a2e200e41b1f6fd1dfd5d8628e0dfd0b0bf545df9ec0d2022214fba08df1fa6e5c254a4bc3269bbc4
7
- data.tar.gz: 55c7b038ec1a3d61e546d58a194e0bf668ffca9989a279df8d8564d052836f579fdb129e203eaed8f913b5aeb6d8f2dacbd0c0da635a7cf51920ded140cf394e
6
+ metadata.gz: fe1a63c8856265ff39b9651474218014a7700da961efb7a5c4adc42106463dd096e30770d520aec072e4df311482c7520c74d141d8448ff8fb948d806e712ad2
7
+ data.tar.gz: f55df1275d2f7efb325e3329e77b0ccc20eba2a5b682d02f80d156188cbf34740ce7053efe2a96b3c3ced63fcfbe1338adafb33377c3cf68ae851e3d60a17c06
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MagicReport
4
+ class GeneralReport
5
+ attr_reader :models, :report_klass, :csv, :fill
6
+
7
+ def initialize(input, report_klass, options = {})
8
+ @models = input.is_a?(Enumerable) ? input : [input]
9
+ @report_klass = report_klass
10
+ @csv = ::MagicReport::Report::Csv.new(self)
11
+ @fill = options[:fill] || false
12
+ end
13
+
14
+ def generate
15
+ models.find_each.with_index do |model, index|
16
+ report = report_klass.new(model, fill)
17
+
18
+ csv.add_headings(report) if index.zero?
19
+ report.rows.each { |row| csv.add_row(row) }
20
+ end
21
+ end
22
+
23
+ def as_attachment
24
+ @as_attachment ||= {
25
+ mime_type: "text/csv",
26
+ content: csv.io.read
27
+ }
28
+ end
29
+ end
30
+ end
@@ -4,16 +4,17 @@ module MagicReport
4
4
  class Report
5
5
  class Builder
6
6
  class Field
7
- def self.build(report, name, processor)
8
- new(report, name, processor)
7
+ def self.build(report, name, processor, options)
8
+ new(report, name, processor, options)
9
9
  end
10
10
 
11
- attr_reader :report, :name, :processor
11
+ attr_reader :report, :name, :processor, :is_primary
12
12
 
13
- def initialize(report, name, processor)
13
+ def initialize(report, name, processor, options)
14
14
  @report = report
15
15
  @name = name
16
16
  @processor = processor
17
+ @is_primary = options.fetch(:primary, false)
17
18
  end
18
19
 
19
20
  def process(model)
@@ -4,14 +4,14 @@ module MagicReport
4
4
  class Report
5
5
  class Builder
6
6
  class HasMany < HasOne
7
- def process_rows(model, row)
8
- extract_relation(model).map.with_index do |rel, idx|
7
+ def process_rows(model, row, is_fill)
8
+ extract_relation(model).flat_map.with_index do |rel, idx|
9
9
  # If we're on a first entry, then we should fill first row
10
10
  # Otherwise will be created a new row
11
11
  if idx.zero?
12
- options[:class].new(rel, row).rows
12
+ options[:class].new(rel, is_fill, row).rows
13
13
  else
14
- options[:class].new(rel).rows
14
+ options[:class].new(rel, is_fill).rows
15
15
  end
16
16
  end
17
17
  end
@@ -30,14 +30,14 @@ module MagicReport
30
30
  relation = extract_relation(model)
31
31
 
32
32
  # Refactor here values method call
33
- options[:class].new(relation).values
33
+ options[:class].new(relation, is_fill).values
34
34
  end
35
35
 
36
- def process_rows(model, row)
36
+ def process_rows(model, row, is_fill)
37
37
  relation = extract_relation(model)
38
38
 
39
39
  # Refactor here values method call
40
- options[:class].new(relation, row).rows
40
+ options[:class].new(relation, is_fill, row).rows
41
41
  end
42
42
 
43
43
  def build_row
@@ -0,0 +1,44 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "csv"
4
+
5
+ module MagicReport
6
+ class Report
7
+ class Csv
8
+ attr_reader :report, :file, :csv
9
+
10
+ def initialize(report)
11
+ @file = Tempfile.new
12
+ @csv = ::CSV.new(@file, write_headers: true)
13
+ end
14
+
15
+ def generate
16
+ write_headers
17
+
18
+ report.rows.each do |row|
19
+ csv << row.to_a
20
+ end
21
+ end
22
+
23
+ def add_headings(report)
24
+ csv << report.headings
25
+ end
26
+
27
+ def add_row(row)
28
+ csv << row.to_a
29
+ end
30
+
31
+ # Don't forget to unlink in production code
32
+ def unlink
33
+ file.close
34
+ file.unlink
35
+ end
36
+
37
+ def io
38
+ io = csv.to_io
39
+ io.rewind
40
+ io
41
+ end
42
+ end
43
+ end
44
+ end
@@ -4,11 +4,12 @@ module MagicReport
4
4
  class Report
5
5
  class Row
6
6
  class Column
7
- attr_reader :key, :heading, :prefix, :value
7
+ attr_reader :key, :heading, :is_primary, :prefix, :value
8
8
 
9
- def initialize(key, heading, prefix)
9
+ def initialize(key, heading, is_primary, prefix)
10
10
  @key = key
11
11
  @heading = heading
12
+ @is_primary = is_primary
12
13
  @prefix = prefix
13
14
  @value = nil
14
15
  end
@@ -18,7 +19,7 @@ module MagicReport
18
19
  end
19
20
 
20
21
  def full_heading
21
- prefix ? "#{prefix} #{heading}" : heading
22
+ prefix.present? ? "#{prefix} #{heading}" : heading
22
23
  end
23
24
  end
24
25
 
@@ -37,8 +38,8 @@ module MagicReport
37
38
  nested_rows[key] = row
38
39
  end
39
40
 
40
- def register_column(key, heading, prefix = nil)
41
- @columns << Column.new(key, heading, prefix)
41
+ def register_column(key, heading, is_primary, prefix = nil)
42
+ @columns << Column.new(key, heading, is_primary, prefix)
42
43
  end
43
44
 
44
45
  def headings
@@ -4,11 +4,12 @@ module MagicReport
4
4
  class Report
5
5
  include Reflection
6
6
 
7
- attr_reader :model, :row
7
+ attr_reader :model, :row, :is_fill
8
8
 
9
- def initialize(model, row = nil)
9
+ def initialize(model, is_fill = false, row = nil)
10
10
  @model = model
11
11
  @row = row || self.class.build_row
12
+ @is_fill = is_fill
12
13
  end
13
14
 
14
15
  def rows
@@ -22,7 +23,7 @@ module MagicReport
22
23
  _has_one.each_value do |has_one|
23
24
  simple_row = row.nested_rows[has_one.name]
24
25
 
25
- has_one.process_rows(model, simple_row)
26
+ has_one.process_rows(model, simple_row, is_fill)
26
27
  end
27
28
 
28
29
  rows.push(row)
@@ -30,17 +31,21 @@ module MagicReport
30
31
  _has_many.each_value do |has_many|
31
32
  simple_row = row.nested_rows[has_many.name]
32
33
 
33
- resik = has_many.process_rows(model, simple_row)
34
+ resik = has_many.process_rows(model, simple_row, is_fill)
34
35
 
35
- resik.shift.map do |resik_row|
36
- new_row = self.class.build_row
36
+ resik.map.with_index do |resik_row, index|
37
+ if index.zero?
38
+ # rows.push(new_row)
39
+ else
40
+ new_row = self.class.build_row
37
41
 
38
- # TODO: copy ID here
39
- # copy_primary_attributes(new_row, row)
42
+ copy_primary_fields(row, new_row)
43
+ # TODO: copy ID here
44
+ # copy_primary_attributes(new_row, row)
45
+ new_row.nested_rows[has_many.name] = resik_row
40
46
 
41
- new_row.nested_rows[has_many.name] = resik_row
42
-
43
- rows.push(new_row)
47
+ rows.push(new_row)
48
+ end
44
49
  end
45
50
  end
46
51
 
@@ -52,6 +57,22 @@ module MagicReport
52
57
  row.headings
53
58
  end
54
59
 
60
+ def copy_primary_fields(old_row, new_row)
61
+ old_row.columns.each do |column|
62
+ if column.is_primary || is_fill
63
+ new_row.add_column_value(key: column.key, value: column.value)
64
+ end
65
+ end
66
+
67
+ if is_fill
68
+ old_row.nested_rows.each do |key, nested_row|
69
+ nested_row.columns.each do |column|
70
+ new_row.nested_rows[key].add_column_value(key: column.key, value: column.value)
71
+ end
72
+ end
73
+ end
74
+ end
75
+
55
76
  class << self
56
77
  # Default i18n scope for locales
57
78
  #
@@ -63,11 +84,14 @@ module MagicReport
63
84
  end
64
85
 
65
86
  def i18n_key
66
- name.underscore.to_sym
87
+ name.underscore.tr("/", ".").to_sym
67
88
  end
68
89
 
69
- def field(name, processor = nil)
70
- reflection = Builder::Field.build(self, name, processor)
90
+ def field(*args)
91
+ options = args.extract_options!
92
+ name, processor = args
93
+
94
+ reflection = Builder::Field.build(self, name, processor, options)
71
95
 
72
96
  Reflection.add_field(self, name, reflection)
73
97
  end
@@ -94,7 +118,7 @@ module MagicReport
94
118
  row = ::MagicReport::Report::Row.new
95
119
 
96
120
  _fields.each_value do |field|
97
- row.register_column(field.name, I18n.t!("#{i18n_scope}.#{i18n_key}.#{field.name}".tr("/", ".")), prefix)
121
+ row.register_column(field.name, I18n.t!("#{i18n_scope}.#{i18n_key}.#{field.name}".tr("/", ".")), field.is_primary, prefix)
98
122
  end
99
123
 
100
124
  _has_one.each_value do |has_one|
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MagicReport
4
- VERSION = "0.7.0"
4
+ VERSION = "0.7.1"
5
5
  end
data/lib/magic_report.rb CHANGED
@@ -5,6 +5,7 @@ require "i18n"
5
5
 
6
6
  require "active_support"
7
7
  require "active_support/core_ext/class/attribute"
8
+ require "active_support/core_ext/array/extract_options"
8
9
  require "active_support/inflector"
9
10
 
10
11
  require "magic_report/version"
@@ -24,5 +25,7 @@ module MagicReport
24
25
 
25
26
  require "magic_report/report/reflection"
26
27
  require "magic_report/report/row"
28
+ require "magic_report/report/csv"
27
29
  require "magic_report/report"
30
+ require "magic_report/general_report"
28
31
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: magic-report
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.7.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Dan Pankratev
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-10-16 00:00:00.000000000 Z
11
+ date: 2025-09-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-types
@@ -60,10 +60,12 @@ extra_rdoc_files: []
60
60
  files:
61
61
  - README.md
62
62
  - lib/magic_report.rb
63
+ - lib/magic_report/general_report.rb
63
64
  - lib/magic_report/report.rb
64
65
  - lib/magic_report/report/builder/field.rb
65
66
  - lib/magic_report/report/builder/has_many.rb
66
67
  - lib/magic_report/report/builder/has_one.rb
68
+ - lib/magic_report/report/csv.rb
67
69
  - lib/magic_report/report/reflection.rb
68
70
  - lib/magic_report/report/row.rb
69
71
  - lib/magic_report/version.rb
@@ -86,7 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
86
88
  - !ruby/object:Gem::Version
87
89
  version: '0'
88
90
  requirements: []
89
- rubygems_version: 3.1.6
91
+ rubygems_version: 3.4.19
90
92
  signing_key:
91
93
  specification_version: 4
92
94
  summary: An easy way to export data to CSV