magic-report 0.6.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: 59c479e22412f34a53caaa404a9febf1186cefe0c0678a9f5c00a4b119f774bf
4
- data.tar.gz: a0d46b4b7226ab1b0c74cd5adc6bd385ef54817ba2e6deb5591b27527e36f507
3
+ metadata.gz: 88305b9a5045e8cd60e96f3ebc8f7991726303f6461cd8de483ccbb483dba5f4
4
+ data.tar.gz: fb088083b95b0aeff7ca7fd4e92fa567e2685ff566ee8c6459582ed1e1876e6d
5
5
  SHA512:
6
- metadata.gz: 715c2887cca5db182f97d578140f9bb44204b70881fc81b0c88ca25033ffd0291d515f08e7e1d8f299c3836324940256622dd63f45e0d90578953a3cbd39f1ef
7
- data.tar.gz: 549a76ff9458405ae70035692cbc88db8c9708a81bd950bc5370c588f5d91316e3753335b30ff4a35c9d5fd55ee211dab7683290b4af3e772fe6b8f43fc71d9a
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
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MagicReport
4
+ class Report
5
+ class Builder
6
+ class Field
7
+ def self.build(report, name, processor, options)
8
+ new(report, name, processor, options)
9
+ end
10
+
11
+ attr_reader :report, :name, :processor, :is_primary
12
+
13
+ def initialize(report, name, processor, options)
14
+ @report = report
15
+ @name = name
16
+ @processor = processor
17
+ @is_primary = options.fetch(:primary, false)
18
+ end
19
+
20
+ def process(model)
21
+ value = extract_value(model)
22
+
23
+ if processor.is_a? Proc
24
+ processor.call(model, value)
25
+ elsif processor.is_a? Symbol
26
+ # Refactor
27
+ report.new(nil).send(processor, model, value)
28
+ else
29
+ value
30
+ end
31
+ end
32
+
33
+ private
34
+
35
+ def extract_value(model)
36
+ model.send(name)
37
+ rescue
38
+ nil
39
+ end
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MagicReport
4
+ class Report
5
+ class Builder
6
+ class HasMany < HasOne
7
+ def process_rows(model, row, is_fill)
8
+ extract_relation(model).flat_map.with_index do |rel, idx|
9
+ # If we're on a first entry, then we should fill first row
10
+ # Otherwise will be created a new row
11
+ if idx.zero?
12
+ options[:class].new(rel, is_fill, row).rows
13
+ else
14
+ options[:class].new(rel, is_fill).rows
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,55 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MagicReport
4
+ class Report
5
+ class Builder
6
+ class HasOne
7
+ def self.build(report, name, options, &extension)
8
+ new(report, name, options, extension)
9
+ end
10
+
11
+ attr_reader :report, :name, :options, :extension, :prefix
12
+
13
+ def initialize(report, name, options, extension)
14
+ @report = report
15
+ @name = name
16
+ @options = options
17
+ @extension = extension
18
+ @prefix = I18n.t!("#{report.i18n_scope}.#{report.i18n_key}.#{name}_relation")
19
+
20
+ unless options[:class]
21
+ klass = ::MagicReport::Report.clone
22
+ klass.define_singleton_method(:name) { "#{report.name}/#{name}" }
23
+ klass.class_eval(&extension)
24
+
25
+ options[:class] = klass
26
+ end
27
+ end
28
+
29
+ def process(model)
30
+ relation = extract_relation(model)
31
+
32
+ # Refactor here values method call
33
+ options[:class].new(relation, is_fill).values
34
+ end
35
+
36
+ def process_rows(model, row, is_fill)
37
+ relation = extract_relation(model)
38
+
39
+ # Refactor here values method call
40
+ options[:class].new(relation, is_fill, row).rows
41
+ end
42
+
43
+ def build_row
44
+ options[:class].build_row(prefix)
45
+ end
46
+
47
+ private
48
+
49
+ def extract_relation(model)
50
+ model.send(name)
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
@@ -8,7 +8,6 @@ module MagicReport
8
8
  attr_reader :report, :file, :csv
9
9
 
10
10
  def initialize(report)
11
- @report = report
12
11
  @file = Tempfile.new
13
12
  @csv = ::CSV.new(@file, write_headers: true)
14
13
  end
@@ -16,17 +15,19 @@ module MagicReport
16
15
  def generate
17
16
  write_headers
18
17
 
19
- [report.result].flatten.each do |row|
20
- value = row.to_h
21
-
22
- if value.is_a?(Array)
23
- value.each { |nested_row| csv << nested_row.values }
24
- else
25
- csv << value.values
26
- end
18
+ report.rows.each do |row|
19
+ csv << row.to_a
27
20
  end
28
21
  end
29
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
+
30
31
  # Don't forget to unlink in production code
31
32
  def unlink
32
33
  file.close
@@ -38,12 +39,6 @@ module MagicReport
38
39
  io.rewind
39
40
  io
40
41
  end
41
-
42
- private
43
-
44
- def write_headers
45
- csv << report.headings
46
- end
47
42
  end
48
43
  end
49
44
  end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module MagicReport
4
+ class Report
5
+ module Reflection
6
+ extend ActiveSupport::Concern
7
+
8
+ included do
9
+ class_attribute :_fields, instance_writer: false, default: {}
10
+ class_attribute :_has_one, instance_writer: false, default: {}
11
+ class_attribute :_has_many, instance_writer: false, default: {}
12
+ end
13
+
14
+ class << self
15
+ def add_field(klass, name, reflection)
16
+ klass._fields = klass._fields.except(name).merge!(name => reflection)
17
+ end
18
+
19
+ def add_has_one(klass, name, reflection)
20
+ klass._has_one = klass._has_one.except(name).merge!(name => reflection)
21
+ end
22
+
23
+ def add_has_many(klass, name, reflection)
24
+ klass._has_many = klass._has_many.except(name).merge!(name => reflection)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -3,61 +3,51 @@
3
3
  module MagicReport
4
4
  class Report
5
5
  class Row
6
- attr_accessor :data, :inner_rows, :nested_rows
6
+ class Column
7
+ attr_reader :key, :heading, :is_primary, :prefix, :value
8
+
9
+ def initialize(key, heading, is_primary, prefix)
10
+ @key = key
11
+ @heading = heading
12
+ @is_primary = is_primary
13
+ @prefix = prefix
14
+ @value = nil
15
+ end
7
16
 
8
- def initialize
9
- @data = {}
10
- @inner_rows = {}
11
- @nested_rows = {}
12
- end
17
+ def assign_value(value)
18
+ @value = value
19
+ end
13
20
 
14
- def add(field:, value:)
15
- data[field] = value
21
+ def full_heading
22
+ prefix.present? ? "#{prefix} #{heading}" : heading
23
+ end
16
24
  end
17
25
 
18
- def add_inner_row(field:, row:)
19
- inner_rows[field] = row
20
- end
26
+ attr_reader :columns, :nested_rows
21
27
 
22
- def add_nested_row(field:, row:)
23
- nested_rows[field] ||= []
24
- nested_rows[field].push(row)
28
+ def initialize
29
+ @columns = []
30
+ @nested_rows = {}
25
31
  end
26
32
 
27
- def values
28
- data.values
33
+ def add_column_value(key:, value:)
34
+ @columns.find { |column| column.key == key }.assign_value(value)
29
35
  end
30
36
 
31
- def complex?
32
- nested_rows.any?
37
+ def add_nested_row(key:, row:)
38
+ nested_rows[key] = row
33
39
  end
34
40
 
35
- def each_nested_row(&block)
36
- nested_rows.keys.flat_map do |key|
37
- nested_rows[key].map do |nested_row|
38
- block.call(nested_row)
39
- end
40
- end
41
+ def register_column(key, heading, is_primary, prefix = nil)
42
+ @columns << Column.new(key, heading, is_primary, prefix)
41
43
  end
42
44
 
43
- def each_inner_row(&block)
44
- inner_rows.values.map do |inner_row|
45
- block.call(inner_row)
46
- end
45
+ def headings
46
+ (columns.map(&:full_heading) + nested_rows.values.map(&:headings)).flatten
47
47
  end
48
48
 
49
- def to_h
50
- @to_h ||= begin
51
- original_hash = inner_rows.any? ? data.merge(each_inner_row { |inner_row| inner_row.to_h }.reduce({}, :merge)) : data
52
-
53
- if complex?
54
- each_nested_row do |nested_row|
55
- original_hash.merge(nested_row.to_h)
56
- end
57
- else
58
- original_hash
59
- end
60
- end
49
+ def to_a
50
+ (columns.map(&:value) + nested_rows.values.map(&:to_a)).flatten
61
51
  end
62
52
  end
63
53
  end
@@ -2,107 +2,135 @@
2
2
 
3
3
  module MagicReport
4
4
  class Report
5
- include ClassHelpers
5
+ include Reflection
6
6
 
7
- attr_reader :fields, :has_one, :has_many, :name, :nested_field, :prefix, :result
7
+ attr_reader :model, :row, :is_fill
8
8
 
9
- def initialize(fields: nil, has_one: nil, has_many: nil, name: nil, prefix: nil, nested_field: nil)
10
- @fields = fields || fields_from_class
11
- @has_one = has_one || has_one_from_class
12
- @has_many = has_many || has_many_from_class
13
- @name = name || name_from_class
14
-
15
- @prefix = prefix
16
- @nested_field = nested_field
9
+ def initialize(model, is_fill = false, row = nil)
10
+ @model = model
11
+ @row = row || self.class.build_row
12
+ @is_fill = is_fill
17
13
  end
18
14
 
19
- def process(input)
20
- @result = ::MagicReport::Report::Process.new(self).call(input)
21
- end
15
+ def rows
16
+ @rows ||= begin
17
+ rows = []
22
18
 
23
- def as_csv
24
- @as_csv ||= begin
25
- csv = ::MagicReport::Report::Csv.new(self)
26
- csv.generate
19
+ _fields.each_value do |field|
20
+ row.add_column_value(key: field.name, value: field.process(model))
21
+ end
27
22
 
28
- csv
29
- end
30
- end
23
+ _has_one.each_value do |has_one|
24
+ simple_row = row.nested_rows[has_one.name]
25
+
26
+ has_one.process_rows(model, simple_row, is_fill)
27
+ end
28
+
29
+ rows.push(row)
30
+
31
+ _has_many.each_value do |has_many|
32
+ simple_row = row.nested_rows[has_many.name]
31
33
 
32
- def as_attachment
33
- {
34
- mime_type: "text/csv",
35
- content: as_csv.io.read
36
- }
34
+ resik = has_many.process_rows(model, simple_row, is_fill)
35
+
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
41
+
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
46
+
47
+ rows.push(new_row)
48
+ end
49
+ end
50
+ end
51
+
52
+ rows
53
+ end
37
54
  end
38
55
 
39
56
  def headings
40
- @headings ||= (fields.map { |field| t(field.key) } + has_one.map { |association| association.report.headings } + has_many.map { |association| association.report.headings }).flatten
57
+ row.headings
41
58
  end
42
59
 
43
- class << self
44
- def t(key)
45
- ::MagicReport::Utils.t(name: name, key: key)
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
46
65
  end
47
66
 
48
- def fields(*attrs)
49
- @fields ||= []
50
-
51
- Types::SymbolArray[attrs].each do |key|
52
- @fields << Configuration::Field.new(key: key)
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
53
72
  end
54
73
  end
74
+ end
55
75
 
56
- def field(*attrs)
57
- key, processor = attrs
76
+ class << self
77
+ # Default i18n scope for locales
78
+ #
79
+ # en:
80
+ # magic_report:
81
+ #
82
+ def i18n_scope
83
+ :magic_report
84
+ end
58
85
 
59
- @fields ||= []
60
- @fields << Configuration::Field.new(key: key, processor: processor)
86
+ def i18n_key
87
+ name.underscore.tr("/", ".").to_sym
61
88
  end
62
89
 
63
- def has_one(attribute, opts = {}, &block)
64
- @has_one ||= []
90
+ def field(*args)
91
+ options = args.extract_options!
92
+ name, processor = args
65
93
 
66
- coerced_attribute = Types::Coercible::Symbol[attribute]
94
+ reflection = Builder::Field.build(self, name, processor, options)
67
95
 
68
- klass = ::MagicReport::Utils.derive_class(opts, &block)
96
+ Reflection.add_field(self, name, reflection)
97
+ end
69
98
 
70
- opts[:name] = ::MagicReport::Utils.underscore(opts[:name].to_s) if opts[:name]
99
+ def fields(*names)
100
+ names.each { |name| field(name) }
101
+ end
71
102
 
72
- if (prefix = opts[:prefix])
73
- opts[:prefix] = new(name: ::MagicReport::Utils.underscore(name.to_s)).instance_exec(&prefix)
74
- end
103
+ def has_one(name, **options, &extension)
104
+ reflection = Builder::HasOne.build(self, name, options, &extension)
75
105
 
76
- @has_one << Configuration::HasOne.new(klass: klass, opts: opts, key: coerced_attribute)
106
+ Reflection.add_has_one(self, name, reflection)
77
107
  end
78
108
 
79
- def has_many(attribute, opts = {}, &block)
80
- @has_many ||= []
109
+ def has_many(name, **options, &extension)
110
+ reflection = Builder::HasMany.build(self, name, options, &extension)
81
111
 
82
- coerced_attribute = Types::Coercible::Symbol[attribute]
83
-
84
- klass = ::MagicReport::Utils.derive_class(opts, &block)
112
+ Reflection.add_has_many(self, name, reflection)
113
+ end
85
114
 
86
- opts[:name] = ::MagicReport::Utils.underscore(opts[:name].to_s) if opts[:name]
115
+ # Building empty row for current report
116
+ # This row doesn't include outer reports
117
+ def build_row(prefix = nil)
118
+ row = ::MagicReport::Report::Row.new
87
119
 
88
- if (prefix = opts[:prefix])
89
- opts[:prefix] = new(name: ::MagicReport::Utils.underscore(name.to_s)).instance_exec(&prefix)
120
+ _fields.each_value do |field|
121
+ row.register_column(field.name, I18n.t!("#{i18n_scope}.#{i18n_key}.#{field.name}".tr("/", ".")), field.is_primary, prefix)
90
122
  end
91
123
 
92
- @has_many << Configuration::HasMany.new(klass: klass, opts: opts, key: coerced_attribute)
93
- end
94
- end
95
-
96
- def resolve_path(key)
97
- nested_field ? "#{nested_field}.#{key}".to_sym : key
98
- end
99
-
100
- private
124
+ _has_one.each_value do |has_one|
125
+ row.add_nested_row(key: has_one.name, row: has_one.build_row)
126
+ end
101
127
 
102
- def t(key)
103
- translated = ::MagicReport::Utils.t(name: name, key: key)
128
+ _has_many.each_value do |has_many|
129
+ row.add_nested_row(key: has_many.name, row: has_many.build_row)
130
+ end
104
131
 
105
- prefix ? "#{prefix} #{translated}" : translated
132
+ row
133
+ end
106
134
  end
107
135
  end
108
136
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module MagicReport
4
- VERSION = "0.6.0"
4
+ VERSION = "0.7.1"
5
5
  end
data/lib/magic_report.rb CHANGED
@@ -3,6 +3,11 @@
3
3
  require "dry-types"
4
4
  require "i18n"
5
5
 
6
+ require "active_support"
7
+ require "active_support/core_ext/class/attribute"
8
+ require "active_support/core_ext/array/extract_options"
9
+ require "active_support/inflector"
10
+
6
11
  require "magic_report/version"
7
12
 
8
13
  module MagicReport
@@ -14,12 +19,13 @@ module MagicReport
14
19
  SymbolArray = Array.of(Types::Coercible::Symbol)
15
20
  end
16
21
 
17
- require "magic_report/utils"
22
+ require "magic_report/report/builder/field"
23
+ require "magic_report/report/builder/has_one"
24
+ require "magic_report/report/builder/has_many"
18
25
 
19
- require "magic_report/report/class_helpers"
20
- require "magic_report/report/configuration"
21
- require "magic_report/report/process"
26
+ require "magic_report/report/reflection"
22
27
  require "magic_report/report/row"
23
28
  require "magic_report/report/csv"
24
29
  require "magic_report/report"
30
+ require "magic_report/general_report"
25
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.6.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-12 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
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: activesupport
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: i18n
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -46,13 +60,14 @@ extra_rdoc_files: []
46
60
  files:
47
61
  - README.md
48
62
  - lib/magic_report.rb
63
+ - lib/magic_report/general_report.rb
49
64
  - lib/magic_report/report.rb
50
- - lib/magic_report/report/class_helpers.rb
51
- - lib/magic_report/report/configuration.rb
65
+ - lib/magic_report/report/builder/field.rb
66
+ - lib/magic_report/report/builder/has_many.rb
67
+ - lib/magic_report/report/builder/has_one.rb
52
68
  - lib/magic_report/report/csv.rb
53
- - lib/magic_report/report/process.rb
69
+ - lib/magic_report/report/reflection.rb
54
70
  - lib/magic_report/report/row.rb
55
- - lib/magic_report/utils.rb
56
71
  - lib/magic_report/version.rb
57
72
  homepage: https://github.com/thefaded/magic-report
58
73
  licenses:
@@ -73,7 +88,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
73
88
  - !ruby/object:Gem::Version
74
89
  version: '0'
75
90
  requirements: []
76
- rubygems_version: 3.1.6
91
+ rubygems_version: 3.4.19
77
92
  signing_key:
78
93
  specification_version: 4
79
94
  summary: An easy way to export data to CSV
@@ -1,23 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module MagicReport
4
- class Report
5
- module ClassHelpers
6
- def name_from_class
7
- ::MagicReport::Utils.underscore(self.class.name)
8
- end
9
-
10
- def fields_from_class
11
- self.class.instance_variable_get(:@fields) || []
12
- end
13
-
14
- def has_one_from_class
15
- self.class.instance_variable_get(:@has_one) || []
16
- end
17
-
18
- def has_many_from_class
19
- self.class.instance_variable_get(:@has_many) || []
20
- end
21
- end
22
- end
23
- end
@@ -1,57 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module MagicReport
4
- class Report
5
- module Configuration
6
- class Field
7
- attr_reader :key, :processor
8
-
9
- def initialize(key:, processor: nil)
10
- @key = key
11
- @processor = processor
12
- end
13
-
14
- def process(entity)
15
- processor ? processor.call(entity) : entity.send(key)
16
- end
17
- end
18
-
19
- class HasOne
20
- attr_reader :klass, :opts, :prefix, :key
21
-
22
- def initialize(klass:, opts:, key:)
23
- @klass = klass
24
- @prefix = opts[:prefix]
25
- @key = key
26
- @opts = opts
27
- end
28
-
29
- def process_entity(entity)
30
- report.process(entity)
31
- end
32
-
33
- def report
34
- @report ||= init_report
35
- end
36
-
37
- private
38
-
39
- # { class: Exports::Supplier, prefix: lambda }
40
-
41
- def init_report
42
- klass.new(report_params)
43
- end
44
-
45
- def report_opts
46
- opts
47
- end
48
-
49
- def report_params
50
- opts.reject { |k, v| %i[class].include? k }.merge(nested_field: key)
51
- end
52
- end
53
-
54
- class HasMany < HasOne; end
55
- end
56
- end
57
- end
@@ -1,59 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module MagicReport
4
- class Report
5
- class Process
6
- attr_reader :report
7
-
8
- def initialize(report)
9
- @report = report
10
- end
11
-
12
- def call(input)
13
- if input.is_a? Enumerable
14
- input.map do |entity|
15
- process_entity(entity)
16
- end
17
- else
18
- process_entity(input)
19
- end
20
- end
21
-
22
- private
23
-
24
- def process_entity(entity)
25
- row = Row.new
26
-
27
- process_fields(entity, row)
28
- process_has_one(entity, row)
29
- process_has_many(entity, row)
30
-
31
- row
32
- end
33
-
34
- def process_fields(entity, row)
35
- report.fields.each do |field|
36
- row.add(field: report.resolve_path(field.key), value: field.process(entity))
37
- end
38
- end
39
-
40
- def process_has_one(entity, row)
41
- report.has_one.each do |association|
42
- inner_row = association.process_entity(entity.send(association.key))
43
-
44
- row.add_inner_row(field: report.resolve_path(association.key), row: inner_row)
45
- end
46
- end
47
-
48
- def process_has_many(entity, row)
49
- report.has_many.each do |association|
50
- entity.send(association.key).each do |entity|
51
- nested_row = association.process_entity(entity)
52
-
53
- row.add_nested_row(field: report.resolve_path(association.key), row: nested_row)
54
- end
55
- end
56
- end
57
- end
58
- end
59
- end
@@ -1,39 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module MagicReport
4
- module Utils
5
- def underscore(klass)
6
- return "ded" unless klass
7
-
8
- klass.gsub(/::/, "/")
9
- .gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2')
10
- .gsub(/([a-z\d])([A-Z])/, '\1_\2')
11
- .tr("-", "_")
12
- .tr("/", ".")
13
- .downcase
14
- end
15
-
16
- def derive_class(opts, &block)
17
- if block
18
- raise "name option must be provided" unless opts[:name]
19
-
20
- cloned_klass = ::MagicReport::Report.clone
21
- cloned_klass.define_singleton_method(:name) { opts[:name] }
22
- cloned_klass.class_eval(&block)
23
- cloned_klass
24
- else
25
- opts[:class]
26
- end
27
- end
28
-
29
- # @param name is the report name
30
- # @key is a field
31
- def t(name:, key:)
32
- I18n.translate!("magic_report.#{name}.#{key}")
33
- end
34
-
35
- module_function :underscore
36
- module_function :derive_class
37
- module_function :t
38
- end
39
- end