csv_factory 0.0.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 ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 1db58c82005a991de32cf94235a6fa248e0cd23da3fef4d78644329e1d2c7938
4
+ data.tar.gz: 9dd04b86df14b7bd738126effd61108508996c5632118c741ae0396cc8d471ab
5
+ SHA512:
6
+ metadata.gz: d7b5f7651ed612c283c6a8b98074a471373c0af11582d1f02ed757d7bee60805f8b7503759d88563058d556584a14c8c12f21f3270756167bf619d8878c61cf3
7
+ data.tar.gz: 974e7ceb9c7d79fd625cc7af6e4427655029a86c171275fc15b484da4ea7df6c6c54a3ae5f837f60f57ff4035d4d95511d23800215d02119d36a39f799612465
data/README.md ADDED
@@ -0,0 +1,86 @@
1
+ # CsvFactory
2
+
3
+ Tool that lets you easily generate csv content given a predefined schema
4
+
5
+ ## Installation
6
+
7
+ Add these lines to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'csv_factory'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install csv_factory
20
+
21
+ ## Usage
22
+ Let's say you need to create a csv file that is pipe (`|`) delimeted and has the following structure:
23
+ - The first row is a Header row with the following columns, in order:
24
+ - `Record Type`
25
+ - `FROM Job Application Name`
26
+ - `TO Job Application Name`
27
+ - Then there's a `Detail` section that contains multiple rows, where each rows has the following columns in order:
28
+ - `Record Type`
29
+ - `Payment Amount`
30
+ - `Payee Name`
31
+ - Lastly, there's a `Trailer` section that is a single row. This row has the following columns in order:
32
+ - `Record Type`
33
+ - `Payments Count`
34
+ - `Total Amount`
35
+
36
+ An example of a file like this would look like this:
37
+ ```
38
+ H|PaymentsApp|Bank
39
+ D|100|Santiago
40
+ D|100|John
41
+ D|100|Phil
42
+ T|3|300
43
+ ```
44
+
45
+ To generate that content using this gem, do the following:
46
+ ```ruby
47
+ csv = CsvFactory::Csv.new(
48
+ delimeter: '|',
49
+ sections: [
50
+ {
51
+ section_name: 'Header',
52
+ columns: [
53
+ { column_name: 'Record Type' },
54
+ { column_name: 'FROM Job Application Name' },
55
+ { column_name: 'TO Job Application Name' },
56
+ ]
57
+ },
58
+ {
59
+ section_name: 'Detail',
60
+ columns: [
61
+ { column_name: 'Record Type' },
62
+ { column_name: 'Payment Amount' },
63
+ { column_name: 'Payee Name' },
64
+ ]
65
+ },
66
+ {
67
+ section_name: 'Trailer',
68
+ columns: [
69
+ { column_name: 'Record Type' },
70
+ { column_name: 'Payments Count' },
71
+ { column_name: 'Total Amount' },
72
+ ]
73
+ }
74
+ ]
75
+ )
76
+
77
+ csv.add_rows_to_section('Header', { 'Record Type' => 'H', 'FROM Job Application Name' => 'PaymentsApp', 'TO Job Application Name' => 'Bank' })
78
+ csv.add_rows_to_section('Detail', [
79
+ { 'Record Type' => 'D', 'Payment Amount' => 100, 'Payee Name' => 'Santiago' },
80
+ { 'Record Type' => 'D', 'Payment Amount' => 100, 'Payee Name' => 'John' },
81
+ { 'Record Type' => 'D', 'Payment Amount' => 100, 'Payee Name' => 'Phil' },
82
+ ])
83
+ csv.add_rows_to_section('Trailer', { 'Record Type' => 'T', 'Payments Count' => 3, 'Total Amount' => 300 } )
84
+ ```
85
+
86
+ And that's it. `csv.generate_content` will return the the csv content exactly as shown above as a string.
@@ -0,0 +1,130 @@
1
+ module CsvFactory
2
+ class Csv
3
+ # Instance variable: @sections
4
+ # Example:
5
+ # [
6
+ # {
7
+ # section_name: 'Header',
8
+ # columns: [
9
+ # { column_name: 'Record Type' },
10
+ # { column_name: 'Environment Type' },
11
+ # ]
12
+ # },
13
+ # {
14
+ # section_name: 'Detail',
15
+ # columns: [
16
+ # { column_name: 'Record Type' },
17
+ # { column_name: 'Business Unit' },
18
+ # { column_name: 'Claim Number' },
19
+ # ]
20
+ # },
21
+ # {
22
+ # section_name: 'Trailer',
23
+ # columns: [
24
+ # { column_name: 'Record Type' },
25
+ # { column_name: 'Total Batch File LineItem Count' },
26
+ # { column_name: 'Total Batch File Amount Total' },
27
+ # ]
28
+ # }
29
+ # ]
30
+ #
31
+ # Instance variable: @column_positions
32
+ # A filter and transformation of the @sections information.
33
+ # Example:
34
+ # {
35
+ # 'Header': {
36
+ # 'Record Type': 0,
37
+ # 'Environment Type': 1
38
+ # },
39
+ # 'Detail': {
40
+ # 'Record Type': 0,
41
+ # 'Business Unit': 1,
42
+ # 'Claim Number': 2,
43
+ # },
44
+ # 'Trailer': {
45
+ # 'Record Type': 0,
46
+ # 'Total Batch File LineItem Count': 1,
47
+ # 'Total Batch File Amount Total': 2
48
+ # }
49
+ # }
50
+ #
51
+ # Instance variable: @data
52
+ # Example:
53
+ # {
54
+ # 'Header': [['value', nil]],
55
+ # 'Detail': [['value', nil, 'value'], ['value', nil, 'value']]
56
+ # 'Trailer': [['value', nil, 'value']]
57
+ # }
58
+ def initialize(delimeter: ',', sections: [])
59
+ @delimeter = delimeter
60
+
61
+ @sections = sections
62
+
63
+ @column_positions = {}
64
+
65
+ # Note: since ruby 1.9, the insertion order is maintained
66
+ # https://www.igvita.com/2009/02/04/ruby-19-internals-ordered-hash
67
+ @data = {}
68
+
69
+ sections.each do |section|
70
+ if @data.key?(section[:section_name])
71
+ raise CsvFactory::Exception.new("The section `#{section[:section_name]}` is defined twice")
72
+ end
73
+
74
+ @column_positions[section[:section_name]] = {}
75
+ section[:columns].each_with_index do |column, idx|
76
+ if @column_positions[section[:section_name]].key?(column[:column_name])
77
+ # NOTE! this is a limitation: this library doesn't support 2 columns of the same name
78
+ # in the same section. Each column name within a section must be unique :(
79
+ raise CsvFactory::Exception.new("The column `#{column[:column_name]}` in the section `#{section[:section_name]}` is defined twice")
80
+ end
81
+
82
+ @column_positions[section[:section_name]][column[:column_name]] = idx
83
+ end
84
+
85
+ @data[section[:section_name]] = []
86
+ end
87
+ end
88
+
89
+ # Parameter: section_name
90
+ # Example: 'Trailer'
91
+ #
92
+ # Parameter: rows
93
+ # Example 1: { 'Record Type': 'T', 'Total Batch File LineItem Count': '21' }
94
+ # Example 2: [{ 'Record Type': 'T', 'Total Batch File LineItem Count': '21' }]
95
+ def add_rows_to_section(section_name, rows)
96
+ unless @data.key?(section_name)
97
+ raise CsvFactory::Exception.new(
98
+ "The section `#{section_name}` is not defined. " \
99
+ 'Maybe it is a symbol/string incosistency with the definition?'
100
+ )
101
+ end
102
+
103
+ unless rows.kind_of?(Array)
104
+ rows = [rows]
105
+ end
106
+
107
+ rows.each do |row|
108
+ new_row = Array.new(@column_positions[section_name].length)
109
+
110
+ row.each do |column_name, value|
111
+ new_row[@column_positions[section_name][column_name]] = value
112
+ end
113
+
114
+ @data[section_name] << new_row
115
+ end
116
+ end
117
+
118
+ def generate_content
119
+ ret_array = []
120
+
121
+ @data.each do |_section_name, rows|
122
+ rows.each do |row|
123
+ ret_array << row.join(@delimeter)
124
+ end
125
+ end
126
+
127
+ ret_array.join("\n")
128
+ end
129
+ end
130
+ end
@@ -0,0 +1,7 @@
1
+ module CsvFactory
2
+ class Exception < StandardError
3
+ def initialize(msg)
4
+ super(msg)
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,3 @@
1
+ module CsvFactory
2
+ VERSION = '0.0.1'.freeze
3
+ end
@@ -0,0 +1,3 @@
1
+ require 'csv_factory/version'
2
+ require 'csv_factory/csv'
3
+ require 'csv_factory/exceptions'
metadata ADDED
@@ -0,0 +1,76 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: csv_factory
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Snapsheet, Inc.
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-08-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '3.8'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '3.8'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '0.12'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '0.12'
41
+ description:
42
+ email:
43
+ - technotifications@snapsheet.me
44
+ executables: []
45
+ extensions: []
46
+ extra_rdoc_files: []
47
+ files:
48
+ - README.md
49
+ - lib/csv_factory.rb
50
+ - lib/csv_factory/csv.rb
51
+ - lib/csv_factory/exceptions.rb
52
+ - lib/csv_factory/version.rb
53
+ homepage: https://github.com/snapsheet/csv_factory
54
+ licenses:
55
+ - MIT
56
+ metadata: {}
57
+ post_install_message:
58
+ rdoc_options: []
59
+ require_paths:
60
+ - lib
61
+ required_ruby_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - "~>"
64
+ - !ruby/object:Gem::Version
65
+ version: '2.2'
66
+ required_rubygems_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ requirements: []
72
+ rubygems_version: 3.0.3
73
+ signing_key:
74
+ specification_version: 4
75
+ summary: Tool that builds CSV files
76
+ test_files: []