stripe-iiftoqbo 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,3 @@
1
+ *~
2
+ .#*
3
+ \#*
data/.rspec ADDED
@@ -0,0 +1,4 @@
1
+ --color
2
+ --format documentation
3
+ -r ./spec/spec_helper.rb
4
+
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ MIT License
2
+ -----------
3
+
4
+ Copyright (c) 2014, Gilman Tolle
5
+
6
+ Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ of this software and associated documentation files (the "Software"), to deal
8
+ in the Software without restriction, including without limitation the rights
9
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ copies of the Software, and to permit persons to whom the Software is
11
+ furnished to do so, subject to the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be included in
14
+ all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,97 @@
1
+ ## Stripe IIF to QuickBooks Online QBO File Translator
2
+
3
+ Does your company use Stripe to charge credit cards?
4
+
5
+ Does your company use QuickBooks Online for accounting?
6
+
7
+ Did you export your full transaction history from Stripe as an .IIF file?
8
+
9
+ Did you hope to import that transaction history into QuickBooks Online to do your taxes?
10
+
11
+ Did you realize that QBO doesn't support importing data from .IIF files, which is what Stripe gave you?
12
+
13
+ Then this tool might be helpful.
14
+
15
+ Stripe-iiftoqbo takes an IIF file and produces a QBO file that you can import into QuickBooks Online.
16
+
17
+ It's pretty hacky, and I've only tested it for my use case. My IIF file had:
18
+
19
+ * Credit Card Payments
20
+ * Subscription Credit Card Payments
21
+ * Credit Card Refunds
22
+ * Transfers to our Checking Account
23
+ * Payouts to Third Parties
24
+ * Stripe Connect Fees Collected
25
+ * Stripe Connect Fees Refunded
26
+ * … and Stripe Transaction Fees, of course :)
27
+
28
+ But now our 2013 taxes are done!
29
+
30
+ I used the Stripe export to come up with our top-line revenue (from credit card payments), and our cost of goods sold (since we're a marketplace, that's payouts to vendors and stripe fees). And all the transfers to our checking account tallied with transfers into our checking account (as seen by our bank).
31
+
32
+ ## Usage
33
+
34
+ Usage: stripe-iiftoqbo [-p PAYMENTS_CSV_FILE] [-c] ACCOUNT_NAME IIF_FILE
35
+
36
+ ## Quickstart
37
+
38
+ First, get your IIF file from Stripe.
39
+
40
+ Go to your Stripe Dashboard, then your account menu, then Account Settings. Go to the Data tab, and hit "Export to Quickbooks". Choose your date range (e.g. all of 2013), and hit Export to IIF.
41
+
42
+ Double-check your file to make sure it's an .IIF.
43
+
44
+ $ head balance_history.iif
45
+ !TRNS TRNSID TRNSTYPE DATE ACCNT AMOUNT MEMO
46
+ !SPL TRNSID TRNSTYPE DATE ACCNT AMOUNT MEMO
47
+ !ENDTRNS
48
+ TRNS PAYOUT (FIRST LAST) 01/23/2014 Third-party Account 135.15 Transfer from Stripe: tr_3MCmCnHFyYXFB5
49
+ SPL PAYOUT (FIRST LAST) 01/23/2014 Stripe Account -135.4 Transfer from Stripe: tr_3MCmCnHFyYXFB5
50
+ SPL GENERAL JOURNAL 01/23/2014 Stripe Payment Processing Fees 0.25 Fees for transfer ID: tr_3MCmCnHFyYXFB5
51
+ ENDTRNS
52
+
53
+ Pick a name for your company (e.g. MyCompanyName). It's going to be saved into the QBO file. I'd recommend using your Stripe Account Name.
54
+
55
+ Then, run the app:
56
+
57
+ ruby -Ilib bin/stripe-iiftoqbo MyCompanyName balance_history.iif > balance_history.qbo
58
+
59
+ You'll get a nice .QBO file with all of your transactions.
60
+
61
+ Now, go to QuickBooks Online. Go to the 'gear' menu and hit 'Chart of Accounts'. Create a new 'Bank' > 'Checking' account and call it 'Stripe'.
62
+
63
+ Now go to the Transactions > Banking page. Hit the dropdown arrow next to Update and choose 'File Upload'.
64
+
65
+ Upload your new .QBO file. You should see the company name you specified, and a date range from the IIF file. Choose your 'Stripe' account from the QuickBooks Online dropdown.
66
+
67
+ You should see a line item for each:
68
+
69
+ * Credit Card Charge you collected
70
+ * Stripe Fee you paid on that charge
71
+ * Transfer to your checking account
72
+ * Transfer to a third-party using Stripe Payounts
73
+ * Stripe Fee you paid on that transfer
74
+ * Stripe Connect Fee you collected
75
+ * Credit Card Charge that was refunded
76
+ * Refund of Stripe Fee for that charge
77
+
78
+ Categorize and accept each transaction. Now you can see how much you made, how much you paid to Stripe, and how much you paid to your vendors.
79
+
80
+ ## Extras
81
+
82
+ If you want to merge the description for each payment into the 'memo' field of your QBO file so you can see them in QuickBooks, go to the Stripe Payments page and export your payments as a CSV. It'll look like this:
83
+
84
+ $ head payments.csv
85
+ id,Description,Created,Amount,Amount Refunded,Currency,Converted Amount,Converted Amount Refunded,Fee,Converted Currency,Mode,Status,Customer ID,Customer Description,Customer Email,Captured,Card Last4,Card Type,Card Exp Month,Card Exp Year,Card Name,Card Address Line1,Card Address Line2,Card Address City,Card Address State,Card Address Country,Card Address Zip,Card Issue Country,Card Fingerprint,Card CVC Status,Card AVS Zip Status,Card AVS Line1 Status,Dispute Status
86
+ ch_3QSlijsVumgdnQ,,2014-02-03 01:47,19.00,0.00,usd,19.00,0.00,0.85,usd,Live,Paid,cus_29a92b191,test@test.com,,true,1111,Visa,1,2016,,,,,,,,US,ztg6Hv5g3sbjBE57,,,,
87
+ ch_3PimG0oAu3LRSg,Test Description To Merge,2014-02-01 02:16,249.00,0.00,usd,249.00,0.00,7.52,usd,Live,Paid,cus_292ab3c2b,test@test.com,,true,2222,Visa,1,2016,,,,,,,,US,2Xv5QDDhdKj23Z0l,,,,
88
+
89
+ Then, run the tool again with ```-p payments.csv```. For each charge in the IIF, if there's a matching Charge ID in the payments file, the tool will merge it into the QBO memo.
90
+
91
+ If you want to inspect the transactions from your .IIF file in CSV format (using Excel, for example), give the '-c' flag. It'll dump CSV instead of QBO.
92
+
93
+ ## License
94
+
95
+ New MIT License - Copyright (c) 2014, Gilman Tolle
96
+
97
+ See LICENSE for details
@@ -0,0 +1,53 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'optparse'
4
+ require 'bigdecimal'
5
+ require 'csv'
6
+ require 'pp'
7
+
8
+ require 'stripe-iiftoqbo'
9
+
10
+ account_id = nil
11
+ iif_file = nil
12
+ dump_csv = false
13
+ payments_file = nil
14
+
15
+ optparser = OptionParser.new do |opts|
16
+ executable_name = File.split($0)[1]
17
+ opts.banner = <<-EOS
18
+
19
+ Usage: #{executable_name} [-p PAYMENTS_CSV_FILE] [-c] ACCOUNT_NAME IIF_FILE
20
+
21
+ Stripe-iiftoqbo converts an .iif file of your live transaction data
22
+ exported from Stripe into a .qbo file that can be imported into
23
+ QuickBooks Online.
24
+
25
+ ACCOUNT_NAME : the name of your Stripe account to be included into your .qbo file (required)
26
+ IIF_FILE : the .iif file to convert (required)
27
+
28
+ EOS
29
+
30
+ opts.on('-p', '--payments [PAYMENTS_CSV_FILE]', "Populate .qbo transaction memo using memo field from a Stripe Payments CSV export") do |filename|
31
+ payments_file = filename
32
+ end
33
+
34
+ opts.on('-c', '--csv', "Output CSV of transactions instead of QBO, for debugging and analysis") do
35
+ dump_csv = true
36
+ end
37
+ end
38
+
39
+ optparser.parse!
40
+
41
+ if ARGV.length < 2
42
+ puts optparser
43
+ exit(-1)
44
+ end
45
+
46
+ iiftoqbo = StripeIIFToQBO::Converter.new( :account_id => ARGV[0],
47
+ :iif_file => ARGV[1],
48
+ :payments_file => payments_file )
49
+ if dump_csv
50
+ puts iiftoqbo.to_csv
51
+ else
52
+ puts iiftoqbo.to_qbo
53
+ end
data/lib/iif/entry.rb ADDED
@@ -0,0 +1,6 @@
1
+ require 'ostruct'
2
+
3
+ module IIF
4
+ class Entry < OpenStruct
5
+ end
6
+ end
data/lib/iif/parser.rb ADDED
@@ -0,0 +1,92 @@
1
+ require 'bigdecimal'
2
+
3
+ require_relative 'transaction'
4
+ require_relative 'entry'
5
+
6
+ module IIF
7
+ class Parser
8
+ attr_accessor :definitions
9
+ attr_accessor :entries
10
+ attr_accessor :transactions
11
+
12
+ def initialize(resource)
13
+ @definitions = {}
14
+ @entries = []
15
+ @transactions = []
16
+
17
+ resource = open_resource(resource)
18
+ resource.rewind
19
+ parse_file(resource)
20
+ create_transactions
21
+ end
22
+
23
+ def open_resource(resource)
24
+ if resource.respond_to?(:read)
25
+ resource
26
+ else
27
+ open(resource)
28
+ end
29
+ rescue Exception
30
+ StringIO.new(resource)
31
+ end
32
+
33
+ def parse_file(resource)
34
+ resource.each_line do |line|
35
+ fields = line.strip.split(/\t/)
36
+ if fields[0][0] == '!'
37
+ parse_definition(fields)
38
+ else
39
+ parse_data(fields)
40
+ end
41
+ end
42
+ end
43
+
44
+ def parse_definition(fields)
45
+ key = fields[0][1..-1]
46
+ values = fields[1..-1]
47
+ @definitions[key] = values.map { |v| v.downcase }
48
+ end
49
+
50
+ def parse_data(fields)
51
+ definition = @definitions[fields[0]]
52
+
53
+ entry = Entry.new
54
+ entry.type = fields[0]
55
+
56
+ fields[1..-1].each_with_index do |field, idx|
57
+ entry.send(definition[idx] + "=", field)
58
+ end
59
+
60
+ entry.amount = BigDecimal.new(entry.amount) if entry.amount
61
+ entry.date = Date.strptime(entry.date, "%m/%d/%Y") if entry.date
62
+
63
+ @entries.push(entry)
64
+ end
65
+
66
+ def create_transactions
67
+ transaction = nil
68
+ in_transaction = false
69
+
70
+ @entries.each do |entry|
71
+
72
+ case entry.type
73
+
74
+ when "TRNS"
75
+ if in_transaction
76
+ @transactions.push(transaction)
77
+ in_transaction = false
78
+ end
79
+ transaction = Transaction.new
80
+ in_transaction = true
81
+
82
+ when "ENDTRNS"
83
+ @transactions.push(transaction)
84
+ in_transaction = false
85
+
86
+ end
87
+
88
+ transaction.entries.push(entry) if in_transaction
89
+ end
90
+ end
91
+ end
92
+ end
@@ -0,0 +1,9 @@
1
+ module IIF
2
+ class Transaction
3
+ attr_accessor :entries
4
+
5
+ def initialize
6
+ self.entries = []
7
+ end
8
+ end
9
+ end
data/lib/iif.rb ADDED
@@ -0,0 +1,15 @@
1
+ require 'iif/parser'
2
+
3
+ def IIF(resource, &block)
4
+ parser = IIF::Parser.new(resource)
5
+
6
+ if block_given?
7
+ if block.arity == 1
8
+ yield parser
9
+ else
10
+ parser.instance_eval(&block)
11
+ end
12
+ end
13
+
14
+ parser
15
+ end
@@ -0,0 +1,14 @@
1
+ module OFX
2
+ class Transaction
3
+ attr_accessor :trntype
4
+ attr_accessor :dtposted
5
+ attr_accessor :trnamt
6
+ attr_accessor :fitid
7
+ attr_accessor :name
8
+ attr_accessor :memo
9
+
10
+ def trnamt=(amt)
11
+ @trnamt = BigDecimal.new(amt)
12
+ end
13
+ end
14
+ end
data/lib/ofx.rb ADDED
@@ -0,0 +1,156 @@
1
+ require "nokogiri"
2
+
3
+ require "ofx/transaction"
4
+
5
+ module OFX
6
+ class Builder
7
+
8
+ attr_accessor :fi_org
9
+ attr_accessor :fi_fid
10
+ attr_accessor :dtserver
11
+
12
+ attr_accessor :bank_id
13
+ attr_accessor :acct_id
14
+ attr_accessor :acct_type # CHECKING, SAVINGS, MONEYMRKT, CREDITLINE
15
+
16
+ attr_accessor :dtstart
17
+ attr_accessor :dtend
18
+
19
+ attr_accessor :transactions
20
+
21
+ attr_accessor :bal_amt
22
+ attr_accessor :dtasof
23
+
24
+ def initialize(&block)
25
+ @headers = [
26
+ [ "OFXHEADER", "100" ],
27
+ [ "DATA", "OFXSGML" ],
28
+ [ "VERSION", "103" ],
29
+ [ "SECURITY", "NONE" ],
30
+ [ "ENCODING", "USASCII" ],
31
+ [ "CHARSET", "1252" ],
32
+ [ "COMPRESSION", "NONE" ],
33
+ [ "OLDFILEUID", "NONE" ],
34
+ [ "NEWFILEUID", "NONE" ]
35
+ ]
36
+ @transactions = []
37
+ self.dtserver = Date.today
38
+ if block_given?
39
+ yield self
40
+ end
41
+ end
42
+
43
+ def bal_amt=(amt)
44
+ @bal_amt = BigDecimal.new(amt)
45
+ end
46
+
47
+ def transaction(&block)
48
+ transaction = OFX::Transaction.new
49
+ yield transaction
50
+ self.transactions.push transaction
51
+ end
52
+
53
+ def to_ofx
54
+ print_headers +
55
+ print_body
56
+ end
57
+
58
+ def print_headers
59
+ @headers.map { |key, value| "#{key}:#{value}" }.join("\n") + "\n\n"
60
+ end
61
+
62
+ def print_body
63
+ builder = Nokogiri::XML::Builder.new do |xml|
64
+ xml.OFX {
65
+ xml.SIGNONMSGSRSV1 {
66
+ xml.SONRS {
67
+ xml.STATUS {
68
+ xml.CODE "0"
69
+ xml.SEVERITY "INFO"
70
+ }
71
+ xml.DTSERVER format_datetime(self.dtserver)
72
+ xml.LANGUAGE "ENG"
73
+ xml.FI {
74
+ xml.ORG self.fi_org
75
+ xml.FID self.fi_fid
76
+ }
77
+ xml.send "INTU.BID", self.fi_fid
78
+ }
79
+ }
80
+ xml.BANKMSGSRSV1 {
81
+ xml.STMTTRNRS {
82
+ xml.TRNUID "0"
83
+ xml.STATUS {
84
+ xml.CODE "0"
85
+ xml.SEVERITY "INFO"
86
+ }
87
+ xml.STMTRS {
88
+ xml.CURDEF "USD"
89
+ xml.BANKACCTFROM {
90
+ xml.BANKID self.bank_id
91
+ xml.ACCTID self.acct_id
92
+ xml.ACCTTYPE self.acct_type
93
+ }
94
+ xml.BANKTRANLIST {
95
+ if self.dtstart
96
+ xml.DTSTART format_date(self.dtstart)
97
+ end
98
+ if self.dtend
99
+ xml.DTEND format_date(self.dtend)
100
+ end
101
+ self.transactions.each do |transaction|
102
+ xml.STMTTRN {
103
+ xml.TRNTYPE format_trntype(transaction.trnamt)
104
+ xml.DTPOSTED format_date(transaction.dtposted)
105
+ xml.TRNAMT format_amount(transaction.trnamt)
106
+ xml.FITID transaction.fitid
107
+ xml.NAME transaction.name
108
+ xml.MEMO transaction.memo
109
+ }
110
+ end
111
+ }
112
+ xml.LEDGERBAL {
113
+ if self.bal_amt
114
+ xml.BALAMT format_balance(self.bal_amt)
115
+ end
116
+ if self.dtasof
117
+ xml.DTASOF format_date(self.dtasof)
118
+ end
119
+ }
120
+ }
121
+ }
122
+ }
123
+ }
124
+ end
125
+ builder.to_xml(:save_with => Nokogiri::XML::Node::SaveOptions::AS_XML | Nokogiri::XML::Node::SaveOptions::NO_DECLARATION)
126
+ end
127
+
128
+ def format_datetime(time)
129
+ time.strftime("%Y%m%d000000")
130
+ end
131
+
132
+ def format_date(time)
133
+ time.strftime("%Y%m%d")
134
+ end
135
+
136
+ def format_amount(amount)
137
+ if amount > 0
138
+ "+#{amount.to_s('F')}"
139
+ else
140
+ "#{amount.to_s('F')}"
141
+ end
142
+ end
143
+
144
+ def format_trntype(amount)
145
+ if amount > 0
146
+ "CREDIT"
147
+ else
148
+ "DEBIT"
149
+ end
150
+ end
151
+
152
+ def format_balance(balance)
153
+ balance.to_s('F')
154
+ end
155
+ end
156
+ end
@@ -0,0 +1,138 @@
1
+ require 'csv'
2
+ require_relative 'iif'
3
+ require_relative 'ofx'
4
+
5
+ module StripeIIFToQBO
6
+ class Converter
7
+ def initialize( options={} )
8
+ @account_id = options[:account_id] if options[:account_id]
9
+ @iif_file = options[:iif_file] if options[:iif_file]
10
+ @payments_file = options[:payments_file] if options[:payments_file]
11
+ @server_time = options[:server_time] || Date.today
12
+
13
+ load_payments_file(@payments_file)
14
+ load_iif_file(@iif_file)
15
+ end
16
+
17
+ def load_payments_file(payments_file)
18
+ @payments = {}
19
+
20
+ if payments_file
21
+ CSV.foreach(payments_file, :headers => true, :encoding => 'windows-1251:utf-8') do |row|
22
+ @payments[row["id"]] = row["Description"] || ""
23
+ end
24
+ end
25
+ end
26
+
27
+ def load_iif_file(iif_file)
28
+ @ofx_entries = []
29
+
30
+ if iif_file
31
+ IIF(iif_file) do |iif|
32
+ iif.transactions.each do |transaction|
33
+ transaction.entries.each do |iif_entry|
34
+ ofx_entry = convert_iif_entry_to_ofx(iif_entry)
35
+ if ofx_entry
36
+ @ofx_entries.push( ofx_entry )
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ def convert_iif_entry_to_ofx(iif_entry)
45
+ ofx_entry = {}
46
+
47
+ ofx_entry[:date] = iif_entry.date
48
+ ofx_entry[:fitid] = iif_entry.memo
49
+ ofx_entry[:accnt] = iif_entry.accnt
50
+ ofx_entry[:trnstype] = iif_entry.trnstype
51
+ ofx_entry[:memo] = iif_entry.memo
52
+
53
+ case iif_entry.accnt
54
+
55
+ when "Stripe Third-party Account"
56
+ ofx_entry[:amount] = -iif_entry.amount
57
+ ofx_entry[:name] = iif_entry.name
58
+ when "Stripe Payment Processing Fees"
59
+ ofx_entry[:amount] = -iif_entry.amount
60
+ ofx_entry[:name] = "Stripe"
61
+ when "Stripe Checking Account"
62
+ ofx_entry[:amount] = -iif_entry.amount
63
+ ofx_entry[:name] = "Transfer to #{iif_entry.accnt}"
64
+ when "Stripe Sales"
65
+ ofx_entry[:amount] = -iif_entry.amount
66
+
67
+ if iif_entry.memo =~ /Stripe Connect fee/
68
+ ofx_entry[:name] = "Stripe Connect Charge"
69
+ elsif iif_entry.memo =~ /Charge/
70
+ ofx_entry[:name] = "Credit Card Charge"
71
+ else
72
+ ofx_entry[:name] = iif_entry.accnt
73
+ end
74
+
75
+ ofx_entry[:memo] =~ /Charge ID: (.*)/
76
+ charge_id = $1
77
+
78
+ if @payments[charge_id]
79
+ ofx_entry[:memo] = "#{@payments[charge_id]} #{iif_entry.memo}"
80
+ end
81
+
82
+ when "Stripe Returns"
83
+ ofx_entry[:amount] = -iif_entry.amount
84
+ ofx_entry[:name] = "Credit Card Refund"
85
+ when "Stripe Account"
86
+ return nil
87
+ end
88
+
89
+ return ofx_entry
90
+ end
91
+
92
+ def to_csv
93
+ rows = []
94
+ rows.push(["Date", "Name", "Account", "Memo", "Amount"].to_csv)
95
+ @ofx_entries.each do |ofx_entry|
96
+ rows.push([ ofx_entry[:date].strftime("%m/%d/%Y"), ofx_entry[:name], ofx_entry[:accnt], "#{ofx_entry[:trnstype]} #{ofx_entry[:memo]}", ofx_entry[:amount].to_s('F') ].to_csv)
97
+ end
98
+ return rows.join
99
+ end
100
+
101
+ def to_qbo
102
+ min_date = nil
103
+ max_date = nil
104
+
105
+ @ofx_entries.each do |e|
106
+ if e[:date]
107
+ min_date = e[:date] if min_date.nil? or e[:date] < min_date
108
+ max_date = e[:date] if max_date.nil? or e[:date] > max_date
109
+ end
110
+ end
111
+
112
+ ofx_builder = OFX::Builder.new do |ofx|
113
+ ofx.dtserver = @server_time
114
+ ofx.fi_org = "Stripe"
115
+ ofx.fi_fid = "0"
116
+ ofx.bank_id = "123456789"
117
+ ofx.acct_id = @account_id
118
+ ofx.acct_type = "CHECKING"
119
+ ofx.dtstart = min_date
120
+ ofx.dtend = max_date
121
+ ofx.bal_amt = 0
122
+ ofx.dtasof = max_date
123
+ end
124
+
125
+ @ofx_entries.each do |ofx_entry|
126
+ ofx_builder.transaction do |ofx_tr|
127
+ ofx_tr.dtposted = ofx_entry[:date]
128
+ ofx_tr.trnamt = ofx_entry[:amount]
129
+ ofx_tr.fitid = ofx_entry[:fitid]
130
+ ofx_tr.name = ofx_entry[:name]
131
+ ofx_tr.memo = ofx_entry[:memo]
132
+ end
133
+ end
134
+
135
+ return ofx_builder.to_ofx
136
+ end
137
+ end
138
+ end
data/spec/iif_spec.rb ADDED
@@ -0,0 +1,43 @@
1
+ describe IIF do
2
+
3
+ empty_iif = File.read(File.dirname(__FILE__) + "/sample-data/empty.iif")
4
+ basic_iif = File.read(File.dirname(__FILE__) + "/sample-data/basic.iif")
5
+
6
+ it "should parse empty IIF files" do
7
+ iif = IIF( empty_iif )
8
+ expect( iif.transactions.length ).to eq(0)
9
+ end
10
+
11
+ it "should parse basic IIF files" do
12
+ iif = IIF( basic_iif )
13
+ expect( iif.transactions.length ).to eq(7)
14
+ first_transaction = iif.transactions.first
15
+ expect( first_transaction.entries.length ).to eq(3)
16
+ first_entry = first_transaction.entries.first
17
+
18
+ expect( first_entry.type ).to eq("TRNS")
19
+ expect( first_entry.trnstype ).to eq("PAYOUT (TEST USER)")
20
+ expect( first_entry.date ).to eq(Date.new(2014,1,23))
21
+ expect( first_entry.accnt ).to eq("Third-party Account")
22
+ expect( first_entry.amount ).to eq(135.15)
23
+ expect( first_entry.memo ).to eq("Transfer from Stripe: tr_3MCmCnHFyYXFB5")
24
+
25
+ second_entry = first_transaction.entries[1]
26
+
27
+ expect( second_entry.type ).to eq("SPL")
28
+ expect( second_entry.trnstype ).to eq("PAYOUT (TEST USER)")
29
+ expect( second_entry.date ).to eq(Date.new(2014,1,23))
30
+ expect( second_entry.accnt ).to eq("Stripe Account")
31
+ expect( second_entry.amount ).to eq(-135.40)
32
+ expect( second_entry.memo ).to eq("Transfer from Stripe: tr_3MCmCnHFyYXFB5")
33
+
34
+ third_entry = first_transaction.entries[2]
35
+
36
+ expect( third_entry.type ).to eq("SPL")
37
+ expect( third_entry.trnstype ).to eq("GENERAL JOURNAL")
38
+ expect( third_entry.date ).to eq(Date.new(2014,1,23))
39
+ expect( third_entry.accnt ).to eq("Stripe Payment Processing Fees")
40
+ expect( third_entry.amount ).to eq(0.25)
41
+ expect( third_entry.memo ).to eq("Fees for transfer ID: tr_3MCmCnHFyYXFB5")
42
+ end
43
+ end
data/spec/ofx_spec.rb ADDED
@@ -0,0 +1,59 @@
1
+ describe OFX do
2
+ empty_ofx = File.read(File.dirname(__FILE__) + "/sample-data/empty.ofx")
3
+ ofx_with_info = File.read(File.dirname(__FILE__) + "/sample-data/with-bank-info.ofx")
4
+ ofx_with_transaction = File.read(File.dirname(__FILE__) + "/sample-data/with-transaction.ofx")
5
+
6
+ it "should generate empty OFX files" do
7
+ ofx_builder = OFX::Builder.new do |ofx|
8
+ ofx.dtserver = Date.new(2014,2,11)
9
+ end
10
+
11
+ ofx = ofx_builder.to_ofx
12
+ expect( ofx ).to eq(empty_ofx)
13
+ end
14
+
15
+ it "should generate OFX files with bank info but no transactions" do
16
+ ofx_builder = OFX::Builder.new do |ofx|
17
+ ofx.dtserver = Date.new(2014,2,11)
18
+ ofx.fi_org = "Stripe"
19
+ ofx.fi_fid = "0"
20
+ ofx.bank_id = "123456789"
21
+ ofx.acct_id = "Test"
22
+ ofx.acct_type = "CHECKING"
23
+ ofx.dtstart = Date.new(2014,1,1)
24
+ ofx.dtend = Date.new(2014,2,1)
25
+ ofx.bal_amt = 0
26
+ ofx.dtasof = Date.new(2014,2,1)
27
+ end
28
+
29
+ ofx = ofx_builder.to_ofx
30
+ expect( ofx ).to eq(ofx_with_info)
31
+ end
32
+
33
+
34
+ it "should generate OFX files with transactions" do
35
+ ofx_builder = OFX::Builder.new do |ofx|
36
+ ofx.dtserver = Date.new(2014,2,11)
37
+ ofx.fi_org = "Stripe"
38
+ ofx.fi_fid = "0"
39
+ ofx.bank_id = "123456789"
40
+ ofx.acct_id = "Test"
41
+ ofx.acct_type = "CHECKING"
42
+ ofx.dtstart = Date.new(2014,1,1)
43
+ ofx.dtend = Date.new(2014,2,1)
44
+ ofx.bal_amt = 0
45
+ ofx.dtasof = Date.new(2014,2,1)
46
+ end
47
+
48
+ ofx_builder.transaction do |ofx_tr|
49
+ ofx_tr.dtposted = Date.new(2014,1,1)
50
+ ofx_tr.trnamt = "100.23"
51
+ ofx_tr.fitid = "Test"
52
+ ofx_tr.name = "Name"
53
+ ofx_tr.memo = "Memo memo"
54
+ end
55
+
56
+ ofx = ofx_builder.to_ofx
57
+ expect( ofx ).to eq(ofx_with_transaction)
58
+ end
59
+ end
@@ -0,0 +1,12 @@
1
+ Date,Name,Account,Memo,Amount
2
+ 01/23/2014,Test User,Third-party Account,PAYOUT (TEST USER) Transfer from Stripe: tr_3MCmCnHFyYXFB5,-135.15
3
+ 01/23/2014,Stripe,Stripe Payment Processing Fees,GENERAL JOURNAL Fees for transfer ID: tr_3MCmCnHFyYXFB5,-0.25
4
+ 01/23/2014,Transfer to Checking Account,Checking Account,DEPOSIT Transfer from Stripe: tr_3MCmQsVsNuIX7J,-85.0
5
+ 01/22/2014,Credit Card Charge,Stripe Sales,GENERAL JOURNAL Charge ID: ch_3M1PskZ2rglde3,249.0
6
+ 01/22/2014,Stripe,Stripe Payment Processing Fees,GENERAL JOURNAL Fees for charge ID: ch_3M1PskZ2rglde3,-7.52
7
+ 07/10/2013,Credit Card Refund,Stripe Returns,GENERAL JOURNAL Refund of charge ch_2AaUvVOXTJxqgU,-60.0
8
+ 07/10/2013,Stripe,Stripe Payment Processing Fees,GENERAL JOURNAL Refund of fees for ch_2AaUvVOXTJxqgU,2.04
9
+ 07/10/2013,Credit Card Charge,Stripe Sales,GENERAL JOURNAL Charge ID: ch_2AaUVt4SQVF5mE,60.0
10
+ 07/10/2013,Stripe,Stripe Payment Processing Fees,GENERAL JOURNAL Fees for charge ID: ch_2AaUVt4SQVF5mE,-2.04
11
+ 12/10/2012,Transfer to Checking Account,Checking Account,DEPOSIT Transfer from Stripe: ach_0qt6m5dlIL2XMq,-15.0
12
+ 12/03/2012,Stripe Connect Charge,Stripe Sales,GENERAL JOURNAL Stripe Connect fee for transaction ID: ch_0qbUpzmgBi6WVJ,15.0
@@ -0,0 +1,28 @@
1
+ !TRNS TRNSID TRNSTYPE DATE ACCNT AMOUNT MEMO
2
+ !SPL TRNSID TRNSTYPE DATE ACCNT AMOUNT MEMO
3
+ !ENDTRNS
4
+ TRNS PAYOUT (TEST USER) 01/23/2014 Third-party Account 135.15 Transfer from Stripe: tr_3MCmCnHFyYXFB5
5
+ SPL PAYOUT (TEST USER) 01/23/2014 Stripe Account -135.4 Transfer from Stripe: tr_3MCmCnHFyYXFB5
6
+ SPL GENERAL JOURNAL 01/23/2014 Stripe Payment Processing Fees 0.25 Fees for transfer ID: tr_3MCmCnHFyYXFB5
7
+ ENDTRNS
8
+ TRNS DEPOSIT 01/23/2014 Checking Account 85.0 Transfer from Stripe: tr_3MCmQsVsNuIX7J
9
+ SPL DEPOSIT 01/23/2014 Stripe Account -85.0 Transfer from Stripe: tr_3MCmQsVsNuIX7J
10
+ ENDTRNS
11
+ TRNS GENERAL JOURNAL 01/22/2014 Stripe Sales -249.0 Charge ID: ch_3M1PskZ2rglde3
12
+ SPL GENERAL JOURNAL 01/22/2014 Stripe Payment Processing Fees 7.52 Fees for charge ID: ch_3M1PskZ2rglde3
13
+ SPL GENERAL JOURNAL 01/22/2014 Stripe Account 241.48 Net for charge ID: ch_3M1PskZ2rglde3
14
+ ENDTRNS
15
+ TRNS GENERAL JOURNAL 07/10/2013 Stripe Returns 60.0 Refund of charge ch_2AaUvVOXTJxqgU
16
+ SPL GENERAL JOURNAL 07/10/2013 Stripe Account -57.96 Refund for refunded charge ID: ch_2AaUvVOXTJxqgU
17
+ SPL GENERAL JOURNAL 07/10/2013 Stripe Payment Processing Fees -2.04 Refund of fees for ch_2AaUvVOXTJxqgU
18
+ ENDTRNS
19
+ TRNS GENERAL JOURNAL 07/10/2013 Stripe Sales -60.0 Charge ID: ch_2AaUVt4SQVF5mE
20
+ SPL GENERAL JOURNAL 07/10/2013 Stripe Payment Processing Fees 2.04 Fees for charge ID: ch_2AaUVt4SQVF5mE
21
+ SPL GENERAL JOURNAL 07/10/2013 Stripe Account 57.96 Net for charge ID: ch_2AaUVt4SQVF5mE
22
+ ENDTRNS
23
+ TRNS DEPOSIT 12/10/2012 Checking Account 15.0 Transfer from Stripe: ach_0qt6m5dlIL2XMq
24
+ SPL DEPOSIT 12/10/2012 Stripe Account -15.0 Transfer from Stripe: ach_0qt6m5dlIL2XMq
25
+ ENDTRNS
26
+ TRNS GENERAL JOURNAL 12/03/2012 Stripe Sales -15.0 Stripe Connect fee for transaction ID: ch_0qbUpzmgBi6WVJ
27
+ SPL GENERAL JOURNAL 12/03/2012 Stripe Account 15.0 Stripe Connect fee for transaction ID: ch_0qbUpzmgBi6WVJ
28
+ ENDTRNS
@@ -0,0 +1,11 @@
1
+ OFXHEADER:100
2
+ DATA:OFXSGML
3
+ VERSION:103
4
+ SECURITY:NONE
5
+ ENCODING:USASCII
6
+ CHARSET:1252
7
+ COMPRESSION:NONE
8
+ OLDFILEUID:NONE
9
+ NEWFILEUID:NONE
10
+
11
+ <OFX><SIGNONMSGSRSV1><SONRS><STATUS><CODE>0</CODE><SEVERITY>INFO</SEVERITY></STATUS><DTSERVER>20140211000000</DTSERVER><LANGUAGE>ENG</LANGUAGE><FI><ORG>Stripe</ORG><FID>0</FID></FI><INTU.BID>0</INTU.BID></SONRS></SIGNONMSGSRSV1><BANKMSGSRSV1><STMTTRNRS><TRNUID>0</TRNUID><STATUS><CODE>0</CODE><SEVERITY>INFO</SEVERITY></STATUS><STMTRS><CURDEF>USD</CURDEF><BANKACCTFROM><BANKID>123456789</BANKID><ACCTID/><ACCTTYPE>CHECKING</ACCTTYPE></BANKACCTFROM><BANKTRANLIST><DTSTART>20121203</DTSTART><DTEND>20140123</DTEND><STMTTRN><TRNTYPE>DEBIT</TRNTYPE><DTPOSTED>20140123</DTPOSTED><TRNAMT>-135.15</TRNAMT><FITID>Transfer from Stripe: tr_3MCmCnHFyYXFB5</FITID><NAME>Test User</NAME><MEMO>Transfer from Stripe: tr_3MCmCnHFyYXFB5</MEMO></STMTTRN><STMTTRN><TRNTYPE>DEBIT</TRNTYPE><DTPOSTED>20140123</DTPOSTED><TRNAMT>-0.25</TRNAMT><FITID>Fees for transfer ID: tr_3MCmCnHFyYXFB5</FITID><NAME>Stripe</NAME><MEMO>Fees for transfer ID: tr_3MCmCnHFyYXFB5</MEMO></STMTTRN><STMTTRN><TRNTYPE>DEBIT</TRNTYPE><DTPOSTED>20140123</DTPOSTED><TRNAMT>-85.0</TRNAMT><FITID>Transfer from Stripe: tr_3MCmQsVsNuIX7J</FITID><NAME>Transfer to Checking Account</NAME><MEMO>Transfer from Stripe: tr_3MCmQsVsNuIX7J</MEMO></STMTTRN><STMTTRN><TRNTYPE>CREDIT</TRNTYPE><DTPOSTED>20140122</DTPOSTED><TRNAMT>+249.0</TRNAMT><FITID>Charge ID: ch_3M1PskZ2rglde3</FITID><NAME>Credit Card Charge</NAME><MEMO>Charge ID: ch_3M1PskZ2rglde3</MEMO></STMTTRN><STMTTRN><TRNTYPE>DEBIT</TRNTYPE><DTPOSTED>20140122</DTPOSTED><TRNAMT>-7.52</TRNAMT><FITID>Fees for charge ID: ch_3M1PskZ2rglde3</FITID><NAME>Stripe</NAME><MEMO>Fees for charge ID: ch_3M1PskZ2rglde3</MEMO></STMTTRN><STMTTRN><TRNTYPE>DEBIT</TRNTYPE><DTPOSTED>20130710</DTPOSTED><TRNAMT>-60.0</TRNAMT><FITID>Refund of charge ch_2AaUvVOXTJxqgU</FITID><NAME>Credit Card Refund</NAME><MEMO>Refund of charge ch_2AaUvVOXTJxqgU</MEMO></STMTTRN><STMTTRN><TRNTYPE>CREDIT</TRNTYPE><DTPOSTED>20130710</DTPOSTED><TRNAMT>+2.04</TRNAMT><FITID>Refund of fees for ch_2AaUvVOXTJxqgU</FITID><NAME>Stripe</NAME><MEMO>Refund of fees for ch_2AaUvVOXTJxqgU</MEMO></STMTTRN><STMTTRN><TRNTYPE>CREDIT</TRNTYPE><DTPOSTED>20130710</DTPOSTED><TRNAMT>+60.0</TRNAMT><FITID>Charge ID: ch_2AaUVt4SQVF5mE</FITID><NAME>Credit Card Charge</NAME><MEMO>Charge ID: ch_2AaUVt4SQVF5mE</MEMO></STMTTRN><STMTTRN><TRNTYPE>DEBIT</TRNTYPE><DTPOSTED>20130710</DTPOSTED><TRNAMT>-2.04</TRNAMT><FITID>Fees for charge ID: ch_2AaUVt4SQVF5mE</FITID><NAME>Stripe</NAME><MEMO>Fees for charge ID: ch_2AaUVt4SQVF5mE</MEMO></STMTTRN><STMTTRN><TRNTYPE>DEBIT</TRNTYPE><DTPOSTED>20121210</DTPOSTED><TRNAMT>-15.0</TRNAMT><FITID>Transfer from Stripe: ach_0qt6m5dlIL2XMq</FITID><NAME>Transfer to Checking Account</NAME><MEMO>Transfer from Stripe: ach_0qt6m5dlIL2XMq</MEMO></STMTTRN><STMTTRN><TRNTYPE>CREDIT</TRNTYPE><DTPOSTED>20121203</DTPOSTED><TRNAMT>+15.0</TRNAMT><FITID>Stripe Connect fee for transaction ID: ch_0qbUpzmgBi6WVJ</FITID><NAME>Stripe Connect Charge</NAME><MEMO>Stripe Connect fee for transaction ID: ch_0qbUpzmgBi6WVJ</MEMO></STMTTRN></BANKTRANLIST><LEDGERBAL><BALAMT>0.0</BALAMT><DTASOF>20140123</DTASOF></LEDGERBAL></STMTRS></STMTTRNRS></BANKMSGSRSV1></OFX>
@@ -0,0 +1 @@
1
+ Date,Name,Account,Memo,Amount
File without changes
@@ -0,0 +1,11 @@
1
+ OFXHEADER:100
2
+ DATA:OFXSGML
3
+ VERSION:103
4
+ SECURITY:NONE
5
+ ENCODING:USASCII
6
+ CHARSET:1252
7
+ COMPRESSION:NONE
8
+ OLDFILEUID:NONE
9
+ NEWFILEUID:NONE
10
+
11
+ <OFX><SIGNONMSGSRSV1><SONRS><STATUS><CODE>0</CODE><SEVERITY>INFO</SEVERITY></STATUS><DTSERVER>20140211000000</DTSERVER><LANGUAGE>ENG</LANGUAGE><FI><ORG/><FID/></FI><INTU.BID/></SONRS></SIGNONMSGSRSV1><BANKMSGSRSV1><STMTTRNRS><TRNUID>0</TRNUID><STATUS><CODE>0</CODE><SEVERITY>INFO</SEVERITY></STATUS><STMTRS><CURDEF>USD</CURDEF><BANKACCTFROM><BANKID/><ACCTID/><ACCTTYPE/></BANKACCTFROM><BANKTRANLIST/><LEDGERBAL/></STMTRS></STMTTRNRS></BANKMSGSRSV1></OFX>
@@ -0,0 +1,11 @@
1
+ OFXHEADER:100
2
+ DATA:OFXSGML
3
+ VERSION:103
4
+ SECURITY:NONE
5
+ ENCODING:USASCII
6
+ CHARSET:1252
7
+ COMPRESSION:NONE
8
+ OLDFILEUID:NONE
9
+ NEWFILEUID:NONE
10
+
11
+ <OFX><SIGNONMSGSRSV1><SONRS><STATUS><CODE>0</CODE><SEVERITY>INFO</SEVERITY></STATUS><DTSERVER>20140211000000</DTSERVER><LANGUAGE>ENG</LANGUAGE><FI><ORG>Stripe</ORG><FID>0</FID></FI><INTU.BID>0</INTU.BID></SONRS></SIGNONMSGSRSV1><BANKMSGSRSV1><STMTTRNRS><TRNUID>0</TRNUID><STATUS><CODE>0</CODE><SEVERITY>INFO</SEVERITY></STATUS><STMTRS><CURDEF>USD</CURDEF><BANKACCTFROM><BANKID>123456789</BANKID><ACCTID/><ACCTTYPE>CHECKING</ACCTTYPE></BANKACCTFROM><BANKTRANLIST/><LEDGERBAL><BALAMT>0.0</BALAMT></LEDGERBAL></STMTRS></STMTTRNRS></BANKMSGSRSV1></OFX>
@@ -0,0 +1,11 @@
1
+ OFXHEADER:100
2
+ DATA:OFXSGML
3
+ VERSION:103
4
+ SECURITY:NONE
5
+ ENCODING:USASCII
6
+ CHARSET:1252
7
+ COMPRESSION:NONE
8
+ OLDFILEUID:NONE
9
+ NEWFILEUID:NONE
10
+
11
+ <OFX><SIGNONMSGSRSV1><SONRS><STATUS><CODE>0</CODE><SEVERITY>INFO</SEVERITY></STATUS><DTSERVER>20140211000000</DTSERVER><LANGUAGE>ENG</LANGUAGE><FI><ORG>Stripe</ORG><FID>0</FID></FI><INTU.BID>0</INTU.BID></SONRS></SIGNONMSGSRSV1><BANKMSGSRSV1><STMTTRNRS><TRNUID>0</TRNUID><STATUS><CODE>0</CODE><SEVERITY>INFO</SEVERITY></STATUS><STMTRS><CURDEF>USD</CURDEF><BANKACCTFROM><BANKID>123456789</BANKID><ACCTID>Test</ACCTID><ACCTTYPE>CHECKING</ACCTTYPE></BANKACCTFROM><BANKTRANLIST><DTSTART>20140101</DTSTART><DTEND>20140201</DTEND></BANKTRANLIST><LEDGERBAL><BALAMT>0.0</BALAMT><DTASOF>20140201</DTASOF></LEDGERBAL></STMTRS></STMTTRNRS></BANKMSGSRSV1></OFX>
@@ -0,0 +1,11 @@
1
+ OFXHEADER:100
2
+ DATA:OFXSGML
3
+ VERSION:103
4
+ SECURITY:NONE
5
+ ENCODING:USASCII
6
+ CHARSET:1252
7
+ COMPRESSION:NONE
8
+ OLDFILEUID:NONE
9
+ NEWFILEUID:NONE
10
+
11
+ <OFX><SIGNONMSGSRSV1><SONRS><STATUS><CODE>0</CODE><SEVERITY>INFO</SEVERITY></STATUS><DTSERVER>20140211000000</DTSERVER><LANGUAGE>ENG</LANGUAGE><FI><ORG>Stripe</ORG><FID>0</FID></FI><INTU.BID>0</INTU.BID></SONRS></SIGNONMSGSRSV1><BANKMSGSRSV1><STMTTRNRS><TRNUID>0</TRNUID><STATUS><CODE>0</CODE><SEVERITY>INFO</SEVERITY></STATUS><STMTRS><CURDEF>USD</CURDEF><BANKACCTFROM><BANKID>123456789</BANKID><ACCTID>Test</ACCTID><ACCTTYPE>CHECKING</ACCTTYPE></BANKACCTFROM><BANKTRANLIST><DTSTART>20140101</DTSTART><DTEND>20140201</DTEND><STMTTRN><TRNTYPE>CREDIT</TRNTYPE><DTPOSTED>20140101</DTPOSTED><TRNAMT>+100.23</TRNAMT><FITID>Test</FITID><NAME>Name</NAME><MEMO>Memo memo</MEMO></STMTTRN></BANKTRANLIST><LEDGERBAL><BALAMT>0.0</BALAMT><DTASOF>20140201</DTASOF></LEDGERBAL></STMTRS></STMTTRNRS></BANKMSGSRSV1></OFX>
@@ -0,0 +1,24 @@
1
+ # This file was generated by the `rspec --init` command. Conventionally, all
2
+ # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3
+ # Require this file using `require "spec_helper"` to ensure that it is only
4
+ # loaded once.
5
+ #
6
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7
+ RSpec.configure do |config|
8
+ config.treat_symbols_as_metadata_keys_with_true_values = true
9
+ config.run_all_when_everything_filtered = true
10
+ # config.filter_run :focus
11
+
12
+ # Run specs in random order to surface order dependencies. If you find an
13
+ # order dependency and want to debug it, you can fix the order by providing
14
+ # the seed, which is printed after each run.
15
+ # --seed 1234
16
+ config.order = 'random'
17
+ end
18
+
19
+ require_relative '../lib/iif'
20
+ require_relative '../lib/ofx'
21
+ require_relative '../lib/stripe-iiftoqbo'
22
+
23
+
24
+
@@ -0,0 +1,31 @@
1
+ describe StripeIIFToQBO do
2
+ empty_qbo = File.read(File.dirname(__FILE__) + "/sample-data/empty.qbo")
3
+ empty_csv = File.read(File.dirname(__FILE__) + "/sample-data/empty.csv")
4
+ basic_iif = File.read(File.dirname(__FILE__) + "/sample-data/basic.iif")
5
+ basic_qbo = File.read(File.dirname(__FILE__) + "/sample-data/basic.qbo")
6
+ basic_csv = File.read(File.dirname(__FILE__) + "/sample-data/basic.csv")
7
+
8
+ it "should create an empty QBO file" do
9
+ iiftoqbo = StripeIIFToQBO::Converter.new( :server_time => Date.new(2014,2,11) )
10
+ qbo = iiftoqbo.to_qbo
11
+ expect( qbo ).to eq(empty_qbo)
12
+ end
13
+
14
+ it "should create an empty CSV file" do
15
+ iiftoqbo = StripeIIFToQBO::Converter.new( :server_time => Date.new(2014,2,11) )
16
+ csv = iiftoqbo.to_csv
17
+ expect( csv ).to eq(empty_csv)
18
+ end
19
+
20
+ it "should create a basic QBO file" do
21
+ iiftoqbo = StripeIIFToQBO::Converter.new( :server_time => Date.new(2014,2,11), :iif_file => basic_iif )
22
+ qbo = iiftoqbo.to_qbo
23
+ expect( qbo ).to eq(basic_qbo)
24
+ end
25
+
26
+ it "should create a basic CSV file" do
27
+ iiftoqbo = StripeIIFToQBO::Converter.new( :server_time => Date.new(2014,2,11), :iif_file => basic_iif )
28
+ csv = iiftoqbo.to_csv
29
+ expect( csv ).to eq(basic_csv)
30
+ end
31
+ end
@@ -0,0 +1,18 @@
1
+ # encoding: utf-8
2
+ Gem::Specification.new do |s|
3
+ s.name = 'stripe-iiftoqbo'
4
+ s.version = '0.1.1'
5
+ s.summary = 'Stripe IIF-to-QBO converter for Quickbooks Online'
6
+ s.description = 'Converts Stripe\'s IIF transaction file into a QBO file for importing into Quickbooks Online. A QBO file is in OFX (Open Financial Exchange) format.'
7
+ s.homepage = 'https://github.com/gtolle/stripe-iiftoqbo'
8
+ s.email = ['gilman.tolle@gmail.com']
9
+ s.authors = ['Gilman Tolle']
10
+ s.license = 'MIT'
11
+ s.files = `git ls-files`.split("\n")
12
+ s.require_paths = ["lib"]
13
+
14
+ s.executables << 'stripe-iiftoqbo'
15
+
16
+ s.add_runtime_dependency 'bigdecimal', '~> 1.2'
17
+ s.add_runtime_dependency 'nokogiri', '~> 1.6'
18
+ end
metadata ADDED
@@ -0,0 +1,106 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: stripe-iiftoqbo
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Gilman Tolle
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-06-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bigdecimal
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.2'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '1.2'
30
+ - !ruby/object:Gem::Dependency
31
+ name: nokogiri
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '1.6'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '1.6'
46
+ description: Converts Stripe's IIF transaction file into a QBO file for importing
47
+ into Quickbooks Online. A QBO file is in OFX (Open Financial Exchange) format.
48
+ email:
49
+ - gilman.tolle@gmail.com
50
+ executables:
51
+ - stripe-iiftoqbo
52
+ extensions: []
53
+ extra_rdoc_files: []
54
+ files:
55
+ - .gitignore
56
+ - .rspec
57
+ - LICENSE
58
+ - README.md
59
+ - bin/stripe-iiftoqbo
60
+ - lib/iif.rb
61
+ - lib/iif/entry.rb
62
+ - lib/iif/parser.rb
63
+ - lib/iif/transaction.rb
64
+ - lib/ofx.rb
65
+ - lib/ofx/transaction.rb
66
+ - lib/stripe-iiftoqbo.rb
67
+ - spec/iif_spec.rb
68
+ - spec/ofx_spec.rb
69
+ - spec/sample-data/basic.csv
70
+ - spec/sample-data/basic.iif
71
+ - spec/sample-data/basic.qbo
72
+ - spec/sample-data/empty.csv
73
+ - spec/sample-data/empty.iif
74
+ - spec/sample-data/empty.ofx
75
+ - spec/sample-data/empty.qbo
76
+ - spec/sample-data/with-bank-info.ofx
77
+ - spec/sample-data/with-transaction.ofx
78
+ - spec/spec_helper.rb
79
+ - spec/stripe-iiftoqbo_spec.rb
80
+ - stripe-iiftoqbo.gemspec
81
+ homepage: https://github.com/gtolle/stripe-iiftoqbo
82
+ licenses:
83
+ - MIT
84
+ post_install_message:
85
+ rdoc_options: []
86
+ require_paths:
87
+ - lib
88
+ required_ruby_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ required_rubygems_version: !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ! '>='
98
+ - !ruby/object:Gem::Version
99
+ version: '0'
100
+ requirements: []
101
+ rubyforge_project:
102
+ rubygems_version: 1.8.25
103
+ signing_key:
104
+ specification_version: 3
105
+ summary: Stripe IIF-to-QBO converter for Quickbooks Online
106
+ test_files: []