transaction_faker 1.0.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.
@@ -0,0 +1,47 @@
1
+ module TransactionFaker
2
+
3
+ class Account
4
+ attr_accessor :balance, :id, :institution_type, :item, :user, :type, :meta
5
+
6
+ def initialize(available_balance, current_balance)
7
+ @id = Faker::Lorem.characters(37)
8
+ @item = Faker::Lorem.characters(37)
9
+ @user = Faker::Lorem.characters(37)
10
+ @institution_type = get_random_institution
11
+ @balance = get_balance(available_balance, current_balance)
12
+ @meta = get_meta
13
+ @type = "depository"
14
+ end
15
+
16
+ def ==(other_account)
17
+ @id = other_account.id
18
+ end
19
+
20
+ private
21
+
22
+ def get_random_institution
23
+ ['amex', 'bofa', 'capone360', 'schwab', 'chase', 'citi', 'fidelity', 'pnc',
24
+ 'svb', 'us', 'usaa', 'wells'].sample
25
+ end
26
+
27
+ def get_balance(available_balance, current_balance)
28
+ balance = {
29
+ "available" => available_balance,
30
+ "current" => current_balance
31
+ }
32
+ end
33
+
34
+ def get_meta
35
+ meta = {
36
+ "name" => get_account_name,
37
+ "number" => Faker::Number.number(4)
38
+ }
39
+ end
40
+
41
+ def get_account_name
42
+ string = Faker::Name.name
43
+ (rand >= 0.5) ? string += "'s Savings" : string += "'s Checking"
44
+ string
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,63 @@
1
+ require 'date'
2
+
3
+ module TransactionFaker
4
+ #Excluded meta
5
+ class Transaction
6
+ attr_accessor :id, :account, :date, :amount, :name, :meta, :location, :pending, :score, :type, :cat, :category, :category_id, :pending_transaction
7
+
8
+ def initialize(account, amount, category_arr, cat_id, month_offset)
9
+ @id = Faker::Lorem.characters(38)
10
+ @account = account
11
+ @date = generate_date(month_offset)
12
+ @amount = amount
13
+ @name = Faker::Company.name
14
+ @location = create_location_hash()
15
+ @pending = false #should this vary?
16
+ @pendingTransaction = nil
17
+ @score = create_score
18
+
19
+ # Here for backwards compatibility only.
20
+ @type = { primary: Categories.get_transaction_type(cat_id) }
21
+ @category = category_arr
22
+ @category_id = cat_id
23
+ @meta = {"location" => @location["coordinates"]}
24
+ end
25
+
26
+ def ==(other_transaction)
27
+ @id == other_transaction.id
28
+ end
29
+
30
+ private
31
+
32
+ def generate_date(month_offset)
33
+ today = Date.today
34
+ month = today.prev_month(month_offset)
35
+
36
+ start_of_month = Date.new(month.year, month.month)
37
+ end_of_month = Date.new(start_of_month.year, start_of_month.month + 1) - 1
38
+
39
+ Faker::Date.between(start_of_month, end_of_month).iso8601
40
+ end
41
+
42
+ def create_location_hash()
43
+ hash = {
44
+ "coordinates" => {
45
+ "lat" => Faker::Address.latitude.to_i,
46
+ "lon" => Faker::Address.longitude.to_i,
47
+ }
48
+ }
49
+ end
50
+
51
+ def create_score
52
+ hash = {
53
+ "master" => 1,
54
+ "detail" => {
55
+ "address" => 1,
56
+ "city" => 1,
57
+ "name" => 1,
58
+ "state" => 1
59
+ }
60
+ }
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,61 @@
1
+ require 'json'
2
+
3
+ module TransactionFaker
4
+ class User
5
+ attr_accessor :account, :transactions, :access_token
6
+
7
+ def initialize(available_balance, current_balance, transaction_hash, seed = nil)
8
+ srand(seed) if seed
9
+ @account = Account.new(available_balance, current_balance)
10
+ @transactions = TransactionHelper::create_transactions(transaction_hash, account)
11
+ @access_token = Faker::Lorem.characters(37)
12
+ end
13
+
14
+ def ==(other_user)
15
+ @account == other_user.account
16
+ end
17
+
18
+ def to_json
19
+ user_hash = {
20
+ accounts: [
21
+ {
22
+ _id: @account.id,
23
+ _item: @account.item,
24
+ _user: @account.user,
25
+ balance: {
26
+ available: @account.balance["available"],
27
+ current: @account.balance["current"]
28
+ },
29
+ institution_type: @account.institution_type,
30
+ meta: @account.meta,
31
+ type: @account.type
32
+ }
33
+ ],
34
+ transactions: add_hash_transactions
35
+ }
36
+ JSON.pretty_generate(user_hash)
37
+ end
38
+
39
+ def add_hash_transactions
40
+ @transactions.map do |transaction|
41
+ {
42
+ _account: transaction.account.id,
43
+ _id: transaction.id,
44
+ amount: transaction.amount,
45
+ date: transaction.date,
46
+ name: transaction.name,
47
+ meta: transaction.meta,
48
+ pending: transaction.pending,
49
+ type: transaction.type,
50
+ category: transaction.category,
51
+ category_id: transaction.category_id,
52
+ score: transaction.score
53
+ }
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+
60
+
61
+
@@ -0,0 +1,52 @@
1
+ require_relative 'categories'
2
+ require_relative 'models/transaction'
3
+ require 'faker'
4
+
5
+ module TransactionFaker
6
+ class TransactionHelper
7
+
8
+ # Returns an array with "amount" number of random values that comply with the
9
+ # mean and the standard_dev.The function gen.rng() will return an error if standard_dev
10
+ # is 0, so 0.000001 provides the same functionality
11
+ def self.normal_distribution(mean, standard_dev, amount)
12
+ standard_dev = 0.000001 if standard_dev == 0
13
+ gen = Rubystats::NormalDistribution.new(mean, standard_dev)
14
+ amount.times.map{ gen.rng().round(2) }
15
+ end
16
+
17
+ #Uses the TransactionHelper objects from the array created in 'create_data' to
18
+ #create an array of transactions over three months.
19
+ def self.create_transactions(transaction_hash, account_id)
20
+ 3.times.flat_map do |month_offset|
21
+ transaction_hash.flat_map do |category, data|
22
+ subcategories = Categories::SUBCATEGORIES[category]
23
+
24
+ normal_distribution(data[:mean], data[:std_dev], data[:monthly_freq]).map do |price|
25
+ category_id = subcategories.sample
26
+ cat_array = create_category_array(category_id)
27
+ Transaction.new(account_id, price, cat_array, category_id.to_s, month_offset + 1)
28
+ end
29
+ end
30
+ end
31
+ end
32
+
33
+ #Returns an array of strings with the category hierarchy,
34
+ # i.e. ["Food and Drink", "Restaurants", "Mexican"]
35
+ def self.create_category_array(id_num)
36
+ array = [
37
+ Categories::FIRST_DIV[convert_id(id_num, 1)],
38
+ Categories::SECOND_DIV[convert_id(id_num, 2)],
39
+ Categories::THIRD_DIV[id_num]
40
+ ].compact
41
+ end
42
+
43
+ #Takes in a transaction ID number and floors it to match its superior category's ID
44
+ #cat_division is either 1 (first category) or 2
45
+ # i.e. 12034890 -> 12034000 or 12034890 -> 12000000
46
+ def self.convert_id(id_num, cat_division)
47
+ divisor = 1000**(3 - cat_division)
48
+ converted_id = ((id_num.to_f / divisor).to_i * divisor)
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,3 @@
1
+ module TransactionFaker
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,36 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'transaction_faker/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "transaction_faker"
8
+ spec.version = TransactionFaker::VERSION
9
+ spec.authors = ["Abiel Gutierrez"]
10
+ spec.email = ["abielg@stanford.com"]
11
+
12
+ spec.summary = %q{Creates fake bank account data and transactions to mimick an API response from Plaid's "Connect" service.}
13
+ spec.homepage = "https://github.com/abielg/transaction-faker"
14
+
15
+ # Prevent pushing this gem to RubyGems.org by setting 'allowed_push_host', or
16
+ # delete this section to allow pushing this gem to any host.
17
+ # if spec.respond_to?(:metadata)
18
+ # spec.metadata['allowed_push_host'] = "https://github.com/abielg/transaction-faker"
19
+ # else
20
+ # raise "RubyGems 2.0 or newer is required to protect against public gem pushes."
21
+ # end
22
+
23
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
24
+ spec.bindir = "exe"
25
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
+ spec.require_paths = ["lib"]
27
+
28
+ spec.add_development_dependency "bundler", "~> 1.10"
29
+ spec.add_development_dependency "rake", "~> 10.0"
30
+ spec.add_development_dependency "rspec"
31
+
32
+ #Gem Dependencies
33
+ spec.add_dependency "faker"
34
+ spec.add_dependency "rubystats"
35
+ spec.add_dependency "descriptive_statistics"
36
+ end
metadata ADDED
@@ -0,0 +1,144 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: transaction_faker
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Abiel Gutierrez
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2015-08-07 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.10'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: faker
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rubystats
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: descriptive_statistics
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ">="
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ description:
98
+ email:
99
+ - abielg@stanford.com
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - ".gitignore"
105
+ - ".rspec"
106
+ - ".travis.yml"
107
+ - Gemfile
108
+ - README.md
109
+ - Rakefile
110
+ - bin/console
111
+ - bin/setup
112
+ - lib/transaction_faker.rb
113
+ - lib/transaction_faker/categories.rb
114
+ - lib/transaction_faker/models/account.rb
115
+ - lib/transaction_faker/models/transaction.rb
116
+ - lib/transaction_faker/models/user.rb
117
+ - lib/transaction_faker/transaction_helper.rb
118
+ - lib/transaction_faker/version.rb
119
+ - transaction_faker.gemspec
120
+ homepage: https://github.com/abielg/transaction-faker
121
+ licenses: []
122
+ metadata: {}
123
+ post_install_message:
124
+ rdoc_options: []
125
+ require_paths:
126
+ - lib
127
+ required_ruby_version: !ruby/object:Gem::Requirement
128
+ requirements:
129
+ - - ">="
130
+ - !ruby/object:Gem::Version
131
+ version: '0'
132
+ required_rubygems_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ requirements: []
138
+ rubyforge_project:
139
+ rubygems_version: 2.4.5
140
+ signing_key:
141
+ specification_version: 4
142
+ summary: Creates fake bank account data and transactions to mimick an API response
143
+ from Plaid's "Connect" service.
144
+ test_files: []