magic-report 0.6.0 → 0.7.0
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 +4 -4
- data/lib/magic_report/report/builder/field.rb +42 -0
- data/lib/magic_report/report/builder/has_many.rb +21 -0
- data/lib/magic_report/report/builder/has_one.rb +55 -0
- data/lib/magic_report/report/reflection.rb +29 -0
- data/lib/magic_report/report/row.rb +29 -40
- data/lib/magic_report/report.rb +73 -69
- data/lib/magic_report/version.rb +1 -1
- data/lib/magic_report.rb +8 -5
- metadata +20 -7
- data/lib/magic_report/report/class_helpers.rb +0 -23
- data/lib/magic_report/report/configuration.rb +0 -57
- data/lib/magic_report/report/csv.rb +0 -49
- data/lib/magic_report/report/process.rb +0 -59
- data/lib/magic_report/utils.rb +0 -39
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d55f3c2c7537067d5b4e825ec2dae5fb4856243aa436c0fc4a24c411124cf826
|
4
|
+
data.tar.gz: f6cb0bd78b371f3649a9fd4cd9df00841a56dfacb4e67bed3074c02e796ab6a3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ef278542203ac22032ec90f68d29cda496d224f18ff38c9a2e200e41b1f6fd1dfd5d8628e0dfd0b0bf545df9ec0d2022214fba08df1fa6e5c254a4bc3269bbc4
|
7
|
+
data.tar.gz: 55c7b038ec1a3d61e546d58a194e0bf668ffca9989a279df8d8564d052836f579fdb129e203eaed8f913b5aeb6d8f2dacbd0c0da635a7cf51920ded140cf394e
|
@@ -0,0 +1,42 @@
|
|
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)
|
8
|
+
new(report, name, processor)
|
9
|
+
end
|
10
|
+
|
11
|
+
attr_reader :report, :name, :processor
|
12
|
+
|
13
|
+
def initialize(report, name, processor)
|
14
|
+
@report = report
|
15
|
+
@name = name
|
16
|
+
@processor = processor
|
17
|
+
end
|
18
|
+
|
19
|
+
def process(model)
|
20
|
+
value = extract_value(model)
|
21
|
+
|
22
|
+
if processor.is_a? Proc
|
23
|
+
processor.call(model, value)
|
24
|
+
elsif processor.is_a? Symbol
|
25
|
+
# Refactor
|
26
|
+
report.new(nil).send(processor, model, value)
|
27
|
+
else
|
28
|
+
value
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
private
|
33
|
+
|
34
|
+
def extract_value(model)
|
35
|
+
model.send(name)
|
36
|
+
rescue
|
37
|
+
nil
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
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)
|
8
|
+
extract_relation(model).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, row).rows
|
13
|
+
else
|
14
|
+
options[:class].new(rel).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).values
|
34
|
+
end
|
35
|
+
|
36
|
+
def process_rows(model, row)
|
37
|
+
relation = extract_relation(model)
|
38
|
+
|
39
|
+
# Refactor here values method call
|
40
|
+
options[:class].new(relation, 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
|
@@ -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,50 @@
|
|
3
3
|
module MagicReport
|
4
4
|
class Report
|
5
5
|
class Row
|
6
|
-
|
6
|
+
class Column
|
7
|
+
attr_reader :key, :heading, :prefix, :value
|
8
|
+
|
9
|
+
def initialize(key, heading, prefix)
|
10
|
+
@key = key
|
11
|
+
@heading = heading
|
12
|
+
@prefix = prefix
|
13
|
+
@value = nil
|
14
|
+
end
|
7
15
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
@nested_rows = {}
|
12
|
-
end
|
16
|
+
def assign_value(value)
|
17
|
+
@value = value
|
18
|
+
end
|
13
19
|
|
14
|
-
|
15
|
-
|
20
|
+
def full_heading
|
21
|
+
prefix ? "#{prefix} #{heading}" : heading
|
22
|
+
end
|
16
23
|
end
|
17
24
|
|
18
|
-
|
19
|
-
inner_rows[field] = row
|
20
|
-
end
|
25
|
+
attr_reader :columns, :nested_rows
|
21
26
|
|
22
|
-
def
|
23
|
-
|
24
|
-
nested_rows
|
27
|
+
def initialize
|
28
|
+
@columns = []
|
29
|
+
@nested_rows = {}
|
25
30
|
end
|
26
31
|
|
27
|
-
def
|
28
|
-
|
32
|
+
def add_column_value(key:, value:)
|
33
|
+
@columns.find { |column| column.key == key }.assign_value(value)
|
29
34
|
end
|
30
35
|
|
31
|
-
def
|
32
|
-
nested_rows
|
36
|
+
def add_nested_row(key:, row:)
|
37
|
+
nested_rows[key] = row
|
33
38
|
end
|
34
39
|
|
35
|
-
def
|
36
|
-
|
37
|
-
nested_rows[key].map do |nested_row|
|
38
|
-
block.call(nested_row)
|
39
|
-
end
|
40
|
-
end
|
40
|
+
def register_column(key, heading, prefix = nil)
|
41
|
+
@columns << Column.new(key, heading, prefix)
|
41
42
|
end
|
42
43
|
|
43
|
-
def
|
44
|
-
|
45
|
-
block.call(inner_row)
|
46
|
-
end
|
44
|
+
def headings
|
45
|
+
(columns.map(&:full_heading) + nested_rows.values.map(&:headings)).flatten
|
47
46
|
end
|
48
47
|
|
49
|
-
def
|
50
|
-
|
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
|
48
|
+
def to_a
|
49
|
+
(columns.map(&:value) + nested_rows.values.map(&:to_a)).flatten
|
61
50
|
end
|
62
51
|
end
|
63
52
|
end
|
data/lib/magic_report/report.rb
CHANGED
@@ -2,107 +2,111 @@
|
|
2
2
|
|
3
3
|
module MagicReport
|
4
4
|
class Report
|
5
|
-
include
|
5
|
+
include Reflection
|
6
6
|
|
7
|
-
attr_reader :
|
7
|
+
attr_reader :model, :row
|
8
8
|
|
9
|
-
def initialize(
|
10
|
-
@
|
11
|
-
@
|
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, row = nil)
|
10
|
+
@model = model
|
11
|
+
@row = row || self.class.build_row
|
17
12
|
end
|
18
13
|
|
19
|
-
def
|
20
|
-
@
|
21
|
-
|
14
|
+
def rows
|
15
|
+
@rows ||= begin
|
16
|
+
rows = []
|
22
17
|
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
csv.generate
|
18
|
+
_fields.each_value do |field|
|
19
|
+
row.add_column_value(key: field.name, value: field.process(model))
|
20
|
+
end
|
27
21
|
|
28
|
-
|
29
|
-
|
30
|
-
|
22
|
+
_has_one.each_value do |has_one|
|
23
|
+
simple_row = row.nested_rows[has_one.name]
|
24
|
+
|
25
|
+
has_one.process_rows(model, simple_row)
|
26
|
+
end
|
27
|
+
|
28
|
+
rows.push(row)
|
31
29
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
30
|
+
_has_many.each_value do |has_many|
|
31
|
+
simple_row = row.nested_rows[has_many.name]
|
32
|
+
|
33
|
+
resik = has_many.process_rows(model, simple_row)
|
34
|
+
|
35
|
+
resik.shift.map do |resik_row|
|
36
|
+
new_row = self.class.build_row
|
37
|
+
|
38
|
+
# TODO: copy ID here
|
39
|
+
# copy_primary_attributes(new_row, row)
|
40
|
+
|
41
|
+
new_row.nested_rows[has_many.name] = resik_row
|
42
|
+
|
43
|
+
rows.push(new_row)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
rows
|
48
|
+
end
|
37
49
|
end
|
38
50
|
|
39
51
|
def headings
|
40
|
-
|
52
|
+
row.headings
|
41
53
|
end
|
42
54
|
|
43
55
|
class << self
|
44
|
-
|
45
|
-
|
56
|
+
# Default i18n scope for locales
|
57
|
+
#
|
58
|
+
# en:
|
59
|
+
# magic_report:
|
60
|
+
#
|
61
|
+
def i18n_scope
|
62
|
+
:magic_report
|
46
63
|
end
|
47
64
|
|
48
|
-
def
|
49
|
-
|
50
|
-
|
51
|
-
Types::SymbolArray[attrs].each do |key|
|
52
|
-
@fields << Configuration::Field.new(key: key)
|
53
|
-
end
|
65
|
+
def i18n_key
|
66
|
+
name.underscore.to_sym
|
54
67
|
end
|
55
68
|
|
56
|
-
def field(
|
57
|
-
|
69
|
+
def field(name, processor = nil)
|
70
|
+
reflection = Builder::Field.build(self, name, processor)
|
58
71
|
|
59
|
-
|
60
|
-
@fields << Configuration::Field.new(key: key, processor: processor)
|
72
|
+
Reflection.add_field(self, name, reflection)
|
61
73
|
end
|
62
74
|
|
63
|
-
def
|
64
|
-
|
65
|
-
|
66
|
-
coerced_attribute = Types::Coercible::Symbol[attribute]
|
75
|
+
def fields(*names)
|
76
|
+
names.each { |name| field(name) }
|
77
|
+
end
|
67
78
|
|
68
|
-
|
79
|
+
def has_one(name, **options, &extension)
|
80
|
+
reflection = Builder::HasOne.build(self, name, options, &extension)
|
69
81
|
|
70
|
-
|
82
|
+
Reflection.add_has_one(self, name, reflection)
|
83
|
+
end
|
71
84
|
|
72
|
-
|
73
|
-
|
74
|
-
end
|
85
|
+
def has_many(name, **options, &extension)
|
86
|
+
reflection = Builder::HasMany.build(self, name, options, &extension)
|
75
87
|
|
76
|
-
|
88
|
+
Reflection.add_has_many(self, name, reflection)
|
77
89
|
end
|
78
90
|
|
79
|
-
|
80
|
-
|
91
|
+
# Building empty row for current report
|
92
|
+
# This row doesn't include outer reports
|
93
|
+
def build_row(prefix = nil)
|
94
|
+
row = ::MagicReport::Report::Row.new
|
81
95
|
|
82
|
-
|
83
|
-
|
84
|
-
|
96
|
+
_fields.each_value do |field|
|
97
|
+
row.register_column(field.name, I18n.t!("#{i18n_scope}.#{i18n_key}.#{field.name}".tr("/", ".")), prefix)
|
98
|
+
end
|
85
99
|
|
86
|
-
|
100
|
+
_has_one.each_value do |has_one|
|
101
|
+
row.add_nested_row(key: has_one.name, row: has_one.build_row)
|
102
|
+
end
|
87
103
|
|
88
|
-
|
89
|
-
|
104
|
+
_has_many.each_value do |has_many|
|
105
|
+
row.add_nested_row(key: has_many.name, row: has_many.build_row)
|
90
106
|
end
|
91
107
|
|
92
|
-
|
108
|
+
row
|
93
109
|
end
|
94
110
|
end
|
95
|
-
|
96
|
-
def resolve_path(key)
|
97
|
-
nested_field ? "#{nested_field}.#{key}".to_sym : key
|
98
|
-
end
|
99
|
-
|
100
|
-
private
|
101
|
-
|
102
|
-
def t(key)
|
103
|
-
translated = ::MagicReport::Utils.t(name: name, key: key)
|
104
|
-
|
105
|
-
prefix ? "#{prefix} #{translated}" : translated
|
106
|
-
end
|
107
111
|
end
|
108
112
|
end
|
data/lib/magic_report/version.rb
CHANGED
data/lib/magic_report.rb
CHANGED
@@ -3,6 +3,10 @@
|
|
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/inflector"
|
9
|
+
|
6
10
|
require "magic_report/version"
|
7
11
|
|
8
12
|
module MagicReport
|
@@ -14,12 +18,11 @@ module MagicReport
|
|
14
18
|
SymbolArray = Array.of(Types::Coercible::Symbol)
|
15
19
|
end
|
16
20
|
|
17
|
-
require "magic_report/
|
21
|
+
require "magic_report/report/builder/field"
|
22
|
+
require "magic_report/report/builder/has_one"
|
23
|
+
require "magic_report/report/builder/has_many"
|
18
24
|
|
19
|
-
require "magic_report/report/
|
20
|
-
require "magic_report/report/configuration"
|
21
|
-
require "magic_report/report/process"
|
25
|
+
require "magic_report/report/reflection"
|
22
26
|
require "magic_report/report/row"
|
23
|
-
require "magic_report/report/csv"
|
24
27
|
require "magic_report/report"
|
25
28
|
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.
|
4
|
+
version: 0.7.0
|
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-
|
11
|
+
date: 2022-10-16 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
|
@@ -47,12 +61,11 @@ files:
|
|
47
61
|
- README.md
|
48
62
|
- lib/magic_report.rb
|
49
63
|
- lib/magic_report/report.rb
|
50
|
-
- lib/magic_report/report/
|
51
|
-
- lib/magic_report/report/
|
52
|
-
- lib/magic_report/report/
|
53
|
-
- lib/magic_report/report/
|
64
|
+
- lib/magic_report/report/builder/field.rb
|
65
|
+
- lib/magic_report/report/builder/has_many.rb
|
66
|
+
- lib/magic_report/report/builder/has_one.rb
|
67
|
+
- lib/magic_report/report/reflection.rb
|
54
68
|
- lib/magic_report/report/row.rb
|
55
|
-
- lib/magic_report/utils.rb
|
56
69
|
- lib/magic_report/version.rb
|
57
70
|
homepage: https://github.com/thefaded/magic-report
|
58
71
|
licenses:
|
@@ -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,49 +0,0 @@
|
|
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
|
-
@report = report
|
12
|
-
@file = Tempfile.new
|
13
|
-
@csv = ::CSV.new(@file, write_headers: true)
|
14
|
-
end
|
15
|
-
|
16
|
-
def generate
|
17
|
-
write_headers
|
18
|
-
|
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
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
# Don't forget to unlink in production code
|
31
|
-
def unlink
|
32
|
-
file.close
|
33
|
-
file.unlink
|
34
|
-
end
|
35
|
-
|
36
|
-
def io
|
37
|
-
io = csv.to_io
|
38
|
-
io.rewind
|
39
|
-
io
|
40
|
-
end
|
41
|
-
|
42
|
-
private
|
43
|
-
|
44
|
-
def write_headers
|
45
|
-
csv << report.headings
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
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
|
data/lib/magic_report/utils.rb
DELETED
@@ -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
|