simple_iif 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +20 -0
- data/Rakefile +9 -0
- data/lib/simple_iif/.DS_Store +0 -0
- data/lib/simple_iif/row_sequence.rb +24 -0
- data/lib/simple_iif/rows/endtrans.rb +6 -0
- data/lib/simple_iif/rows/spl.rb +39 -0
- data/lib/simple_iif/rows/trans.rb +64 -0
- data/lib/simple_iif/rows/vend.rb +41 -0
- data/lib/simple_iif/rows.rb +95 -0
- data/lib/simple_iif/version.rb +3 -0
- data/lib/simple_iif.rb +6 -0
- data/simple_iif.gemspec +17 -0
- data/test/test_row_sequence.rb +81 -0
- data/test/test_rows.rb +83 -0
- metadata +64 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 The Pragmatic Bookshelf
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
# SimpleIif
|
2
|
+
|
3
|
+
A trivial library to assist in handling QuickBooks iif files.
|
4
|
+
|
5
|
+
I know: iif is a deprecated format. But it's all I have to play with on QuickBooks for Mac.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
Add this line to your application's Gemfile:
|
10
|
+
|
11
|
+
gem 'simple_iif'
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install simple_iif
|
20
|
+
|
data/Rakefile
ADDED
Binary file
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module SimpleIif
|
2
|
+
class RowSequence
|
3
|
+
|
4
|
+
def initialize
|
5
|
+
@rows = []
|
6
|
+
end
|
7
|
+
|
8
|
+
def add(row_type, *row_params, &block)
|
9
|
+
new_row = Rows.for(row_type, *row_params)
|
10
|
+
@rows << new_row
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_iif
|
14
|
+
result = []
|
15
|
+
@rows.each do |row|
|
16
|
+
result << row.headers.join("\t")
|
17
|
+
end
|
18
|
+
@rows.each do |row|
|
19
|
+
result << row.values.join("\t")
|
20
|
+
end
|
21
|
+
result
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module SimpleIif
|
2
|
+
class Rows::Spl < Rows
|
3
|
+
|
4
|
+
register("SPL")
|
5
|
+
|
6
|
+
@all_fields = [
|
7
|
+
' SPLID', #(Required) A unique number that identifies the distribution line in the transaction.
|
8
|
+
' TRNSTYPE', #A keyword that indicates the type of transaction. The keyword in this field must match the keyword in the TRNSTYPE field for the transaction. The keyword will be one of the following:
|
9
|
+
# BILL: Bills from vendors
|
10
|
+
# CHECK: Checks
|
11
|
+
# DEPOSIT: Bank or money market deposits
|
12
|
+
# INVOICE: Invoices
|
13
|
+
# PAYMENT: Customer payments
|
14
|
+
' DATE', #The date of the transaction. The date in this field must match the date in the DATE field for the transaction.
|
15
|
+
'*ACCNT', #(Required) The income or expense account to which you assigned the amount on the distribution line.
|
16
|
+
' NAME', #The name of the customer, vendor, payee, or employee.
|
17
|
+
' CLASS', #The name of the class that applies to the distribution amount. If the class is a subclass, the class name includes the names of the parent classes, beginning with the highest level class. A colon (:) separates each class name.
|
18
|
+
'*AMOUNT', #(Required) The distribution amount. Credit amounts are negative.
|
19
|
+
' DOCNUM', #The number of the transaction. For checks, the number is the check number; for invoices, the number is the invoice number, etc.
|
20
|
+
' MEMO', #The memo text associated with the distribution line.
|
21
|
+
' CLEAR', #Indicates whether the distribution amount has cleared. These keywords can appear in the CLEAR field: Y or N
|
22
|
+
' PRICE', #The unit cost of the item.
|
23
|
+
' QNTY', #The number of items sold. This value is part of a line item on an invoice, credit memo, or sales receipt.
|
24
|
+
' INVITEM', #The type of items sold. This value is part of a line item on an invoice, credit memo, or sales receipt.
|
25
|
+
' PAYMETH', #On a sales receipt, indicates the method of payment (check, credit card, etc.) that the customer used.
|
26
|
+
' TAXABLE', #Indicates that a line item on an invoice, credit memo, or sales receipt is taxable.
|
27
|
+
' REIMBEXP', #Indicates the status of the distribution amount as a reimbursable expense. These codes can appear under REIMBEXP:
|
28
|
+
# NONEED: Indicates that the distribution amount does not qualify as a reimbursable expense.
|
29
|
+
# NOTHING: Indicates that the distribution amount can be billed to a customer as a reimbursable expense.
|
30
|
+
# THISWAS: Indicates that the distribution amount is a reimbursable expense that appears on an invoice or sales receipt.
|
31
|
+
# HASBEEN: Identifies a distribution amount on a check that has been billed to a customer as a reimbursable expense.
|
32
|
+
# EXTRA: Adds additional information about the distribution line. These keywords can appear in the EXTRA field:
|
33
|
+
|
34
|
+
' ENDGRP', #(Invoices, credit memos, and sales receipts only) Indicates that the distribution line is the last item of an invoice item group.
|
35
|
+
' AUTOSTAX', #Identifies a sales tax item as the automatic tax rate you set up for your QuickBooks company.
|
36
|
+
' VALDAJ', #(Inventory) Indicates whether the amount in a detail line is an inventory value adjustment. Y or N
|
37
|
+
]
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# -*- coding: utf-8 -*-
|
2
|
+
module SimpleIif
|
3
|
+
class Rows::Trans < Rows
|
4
|
+
register("TRNS")
|
5
|
+
|
6
|
+
@all_fields = [
|
7
|
+
' TRNSID', #A unique number that identifies the transaction.
|
8
|
+
' TIMESTAMP', #A second unique number that works with TRNSID to identify the transaction.
|
9
|
+
' TRNSTYPE', #(Required) A keyword that identifies the type of transaction. These keywords can appear in the TRNSTYPE field:
|
10
|
+
# BEGINBALCHECK: Transactions that create a beginning balance in a balance sheet account
|
11
|
+
# BILL: Bills from vendors
|
12
|
+
# BILL REFUND: Refunds from a vendor
|
13
|
+
# CASH REFUND: Cash refunds you give to customers
|
14
|
+
# CASH SALE: Sales receipts
|
15
|
+
# CCARD REFUND: Refunds you receive on credit card charges
|
16
|
+
# CHECK: Checks
|
17
|
+
# CREDIT CARD: Charges you make on a credit card
|
18
|
+
# CREDIT MEMO: Credit you give to customers for merchandise they return
|
19
|
+
# DEPOSIT: Bank or money market deposits
|
20
|
+
# ESTIMATES: Estimates or bids
|
21
|
+
# GENERAL JOURNAL: General journal transactions
|
22
|
+
# INVOICE: Invoices
|
23
|
+
# PAYMENT: Customer payments
|
24
|
+
# PURCHORD: Purchase orders
|
25
|
+
# TRANSFER: Transfers of funds from one balance sheet account to another
|
26
|
+
'*DATE', #The date of the transaction. The date is always in MM/DD/YY format. For example, 1/30/94.
|
27
|
+
'*ACCNT', #(Required) The name of the account assigned to the transaction.
|
28
|
+
' NAME', #The name of the customer, vendor, payee, or employee.
|
29
|
+
' CLASS', #The name of the class that applies to the transaction. If the class is a subclass, the class name includes the names of the parent classes, beginning with the highest level class. A colon (:) separates each class name.
|
30
|
+
'*AMOUNT', #(Required) The amount of the transaction. Debit amounts are always positive, credit amounts are always negative.
|
31
|
+
' DOCNUM', #The number of the transaction. For checks, the number is the check number; for invoices, the number is the invoice number; etc.
|
32
|
+
' MEMO', #The memo text associated with the transaction.
|
33
|
+
' CLEAR', #Indicates whether the transaction has cleared. These keywords can appear in the CLEAR field: Y or N
|
34
|
+
' TOPRINT', #Indicates whether a check, invoice, credit memo, or sales receipt has been marked as "To be printed." These keywords can appear in the TOPRINT field: Y or N
|
35
|
+
' ADDR1', #The first line of the customer's, vendor's, payee's, or employee's address.
|
36
|
+
' ADDR2', #The second line of the customer's, vendor's, payee's, or employee's address.
|
37
|
+
' ADDR3', #The third line of the customer's, vendor's, payee's, or employee's address.
|
38
|
+
' ADDR4', #The fourth line of the customer's, vendor's, payee's, or employee's address.
|
39
|
+
' ADDR5', #The fifth line of the customer's, vendor's, payee's, or employee's address.
|
40
|
+
' DUEDATE', #(Bills and invoices only) The due date of the bill payment or invoice payment. The date is always in MM/DD/YY format. For example, 1/30/98.
|
41
|
+
' TERMS', #(Invoices only) The terms of the invoice.
|
42
|
+
' PAID', #(Invoices only) Indicates whether an invoice has been paid in full. These keywords can appear in the PAID field: Y or N
|
43
|
+
' PAYMETH', #(Sales receipts only) The method your customer used to pay for the merchandise.
|
44
|
+
' SHIPVIA', #(Invoices and sales receipts only) The method you used to ship the merchandise.
|
45
|
+
' SHIPDATE', #(Invoices and sales receipts only) The shipping date. If you are creating an import file, enter the date in MM/DD/YY format. For example, 1/30/94.
|
46
|
+
' REP', #(Invoices and sales receipts only) The initials of the sales representative or employee who made the sale.
|
47
|
+
' FOB', #(Invoices, credit memos, and cash sales only) The location where you delivered the merchandise—free of charge—to a carrier for shipment.
|
48
|
+
' PONUM', #(Invoices and credit memos only) The customer's purchase order number.
|
49
|
+
' INVTITLE', #(Invoices, credit memos, and sales receipts only) The title that appears on the invoice, credit memo, or sales receipt.
|
50
|
+
' INVMEMO', #(Invoices, credit memos, and sales receipts only) Your message to the customer—as it appears on the invoice, credit memo, or sales receipt.
|
51
|
+
' SADDR1', #(Invoices and sales receipts only) The first line of the customer's shipping address.
|
52
|
+
' SADDR2', #(Invoices and sales receipts only) The second line of the customer's shipping address.
|
53
|
+
' SADDR3', #(Invoices and sales receipts only) The third line of the customer's shipping address.
|
54
|
+
' SADDR4', #(Invoices and sales receipts only) The fourth line of the customer's shipping address.
|
55
|
+
' SADDR5', #(Invoices and sales receipts only) The fifth line of the customer's shipping address.
|
56
|
+
' NAMEISTAXABLE', #(Invoices and sales receipts only) Indicates whether the customer whose name appears in the transaction is taxable. Y or N
|
57
|
+
]
|
58
|
+
|
59
|
+
def closing_row_name
|
60
|
+
'ENDTRNS'
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module SimpleIif
|
2
|
+
class Rows::Vend < Rows
|
3
|
+
register("VEND")
|
4
|
+
|
5
|
+
@all_fields = [
|
6
|
+
'*NAME', #(Required) The name of the vendor.
|
7
|
+
' TIMESTAMP', #(Export files only) A unique number that identifies the company file from which you exported the Vendor list.
|
8
|
+
' REFNUM', #(Export files only) A unique number that identifies an entry in the list.
|
9
|
+
'*PRINTAS', #The name you would like checks to be made out to. This field allows you to make checks out to a different name than the name that appears on your Vendor list.
|
10
|
+
'*ADDR1', #The first line of the vendor's address.
|
11
|
+
'*ADDR2', #The second line of the vendor's address.
|
12
|
+
' ADDR3', #The third line of the vendor's address.
|
13
|
+
' ADDR4', #The fourth line of the vendor's address.
|
14
|
+
' ADDR5', #The fifth line of the vendor's address.
|
15
|
+
'*VTYPE', #Your classification for the vendor (QuickBooks calls this a "vendor type"). If you import a vendor type that is not on your Vendor Type list, QuickBooks adds the new vendor type to the list.
|
16
|
+
' CONT1', #The name of your primary contact with the vendor.
|
17
|
+
' PHONE1', #The vendor's phone number.
|
18
|
+
' PHONE2', #The vendor's alternate phone number.
|
19
|
+
' FAXNUM', #The vendor's FAX number.
|
20
|
+
' TAXID', #The vendor's tax identification number.
|
21
|
+
' LIMIT', #Your credit limit with the vendor. If you are creating an import file, enter the dollar amount.
|
22
|
+
' TERMS', #Your payment terms with the vendor.
|
23
|
+
' NOTEPAD', #Your notes about the vendor. If you are creating an import file, the notes appear in the Notepad window for the vendor.
|
24
|
+
' SALUTATION', #The vendor's salutation, or title (Mr., Ms., Doctor, etc.).
|
25
|
+
' COMPANYNAME',#The name of the vendor's company.
|
26
|
+
'*FIRSTNAME', #The vendor's first name.
|
27
|
+
' MIDINIT', #The vendor's middle initial.
|
28
|
+
'*LASTNAME', #The vendor's last name.
|
29
|
+
' CUSTFLD1', #CUSTFLD2
|
30
|
+
' CUSTFLD2', #CUSTFLD2
|
31
|
+
' CUSTFLD3', #CUSTFLD2
|
32
|
+
' CUSTFLD4', #CUSTFLD2
|
33
|
+
' CUSTFLD5', #CUSTFLD2
|
34
|
+
' CUSTFLD6', #CUSTFLD2
|
35
|
+
' CUSTFLD7', #The custom field entries for the vendor (you can have up to 7 custom field entries). Custom fields let you track special information about the vendor, such as the vendor's birthday or e-mail address. What you use custom fields for is entirely up to you.
|
36
|
+
'*1099', #Indicates whether you file a 1099-MISC form for this vendor. If you are creating an import file, enter one of these keywords in the 1099 field:
|
37
|
+
' NOTE', #The name or number of the account you want to associate with this vendor. QuickBooks requires an account number if you want to set up this vendor as an online payee. The payee uses this number to identify you.
|
38
|
+
]
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require_relative 'row_sequence'
|
2
|
+
|
3
|
+
module SimpleIif
|
4
|
+
class Rows
|
5
|
+
|
6
|
+
# Load in the subclasses defining each row type
|
7
|
+
ROWS = {}
|
8
|
+
|
9
|
+
def self.register(row_type)
|
10
|
+
ROWS[row_type] = self
|
11
|
+
self.instance_eval %{
|
12
|
+
def row_type
|
13
|
+
"#{row_type}"
|
14
|
+
end
|
15
|
+
}
|
16
|
+
end
|
17
|
+
|
18
|
+
class << self
|
19
|
+
def required_fields
|
20
|
+
@required_fields ||= @all_fields.grep(/^\*/).map {|f| f[1..-1] }
|
21
|
+
end
|
22
|
+
|
23
|
+
def optional_fields
|
24
|
+
@optional_fields ||= @all_fields.grep(/^ /).map {|f| f[1..-1] }
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
row_definitions = Dir.chdir(File.join(File.dirname(__FILE__))) { Dir.glob("rows/*.rb")}
|
30
|
+
row_definitions.each do |row|
|
31
|
+
require_relative row
|
32
|
+
end
|
33
|
+
|
34
|
+
# An an object that represents a set of transaction rows
|
35
|
+
def self.sequence
|
36
|
+
RowSequence.new
|
37
|
+
end
|
38
|
+
|
39
|
+
# Factory that returns a new row for a given type
|
40
|
+
def self.for(row, *args)
|
41
|
+
if cls = ROWS[row.to_s.upcase]
|
42
|
+
cls.new(*args)
|
43
|
+
else
|
44
|
+
fail "Don't know about row #{row.inspect}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
# Now the instance stuff
|
50
|
+
|
51
|
+
attr_reader :data
|
52
|
+
|
53
|
+
def initialize(values = {})
|
54
|
+
@data = {}
|
55
|
+
values.each do |key, value|
|
56
|
+
key = key.to_s.upcase
|
57
|
+
if valid_field?(key)
|
58
|
+
@data[key] = value
|
59
|
+
else
|
60
|
+
puts self.class.required_fields.sort
|
61
|
+
puts "----"
|
62
|
+
puts self.class.optional_fields.sort
|
63
|
+
fail "Row type #{self.class.row_type} does not have a field #{key}"
|
64
|
+
end
|
65
|
+
end
|
66
|
+
check_all_required_fields_present
|
67
|
+
end
|
68
|
+
|
69
|
+
def valid_field?(field_name)
|
70
|
+
self.class.required_fields.include?(field_name) ||
|
71
|
+
self.class.optional_fields.include?(field_name)
|
72
|
+
end
|
73
|
+
|
74
|
+
def headers
|
75
|
+
["!#{self.class.row_type}"] + @data.keys.sort
|
76
|
+
end
|
77
|
+
|
78
|
+
def values
|
79
|
+
["#{self.class.row_type}"] + @data.keys.sort.map {|k| @data[k]}
|
80
|
+
end
|
81
|
+
|
82
|
+
def to_iif
|
83
|
+
[ headers.join("\t"), values.join("\t") ]
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
def check_all_required_fields_present
|
89
|
+
missing = self.class.required_fields.select {|f| !@data.has_key?(f) }
|
90
|
+
unless missing.empty?
|
91
|
+
fail "Missing required fields: #{missing.join(', ')}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
data/lib/simple_iif.rb
ADDED
data/simple_iif.gemspec
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/simple_iif/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Dave Thomas"]
|
6
|
+
gem.email = ["dave@pragprog.com"]
|
7
|
+
gem.description = %q{A simple library to assist in the handling of Quickbooks IIF files}
|
8
|
+
gem.summary = gem.description
|
9
|
+
gem.homepage = ""
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "simple_iif"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = SimpleIif::VERSION
|
17
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'shoulda'
|
3
|
+
require 'simple_iif/rows'
|
4
|
+
|
5
|
+
include SimpleIif
|
6
|
+
|
7
|
+
class TestRowSequence < Test::Unit::TestCase
|
8
|
+
|
9
|
+
def setup
|
10
|
+
@rs = RowSequence.new
|
11
|
+
end
|
12
|
+
|
13
|
+
context "An empty row sequence" do
|
14
|
+
should "have no headers or values" do
|
15
|
+
assert_equal [], @rs.to_iif
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context "A row sequence containing a vendor" do
|
20
|
+
setup do
|
21
|
+
@params = {
|
22
|
+
name: "Dave Thomas",
|
23
|
+
printas: "Mr Smith",
|
24
|
+
addr1: "123 Main St",
|
25
|
+
addr2: "Anytown",
|
26
|
+
vtype: "Author",
|
27
|
+
firstname: "David",
|
28
|
+
lastname: "Thomas",
|
29
|
+
:'1099' => "YES"
|
30
|
+
}
|
31
|
+
|
32
|
+
@rs.add(:vend, @params)
|
33
|
+
@iif = @rs.to_iif
|
34
|
+
end
|
35
|
+
|
36
|
+
should "contain two lines of iff data" do
|
37
|
+
assert_equal 2, @iif.size
|
38
|
+
end
|
39
|
+
|
40
|
+
should "contain a valid header" do
|
41
|
+
hdr = @iif.first
|
42
|
+
assert_not_nil hdr
|
43
|
+
fields = hdr.split("\t")
|
44
|
+
assert_equal "!VEND", fields.shift
|
45
|
+
expected = @params.keys.map(&:to_s).map(&:upcase).sort
|
46
|
+
assert_equal expected, fields
|
47
|
+
end
|
48
|
+
|
49
|
+
should "contain the values" do
|
50
|
+
hdrs = @iif.first.split("\t")[1..-1].map(&:downcase).map(&:to_sym)
|
51
|
+
data = @iif.last
|
52
|
+
fields = data.split("\t")
|
53
|
+
assert_equal "VEND", fields.shift
|
54
|
+
assert_equal hdrs.size, fields.size
|
55
|
+
hdrs.zip(fields).each do |hdr, field|
|
56
|
+
assert_equal @params[hdr], field
|
57
|
+
@params.delete(hdr)
|
58
|
+
end
|
59
|
+
assert @params.empty?, "All headers should have been used"
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context "a row sequence containing 2 rows" do
|
64
|
+
setup do
|
65
|
+
@rs.add(:trns, date: '1/2/3', accnt: 'bank', amount: '12.34')
|
66
|
+
@rs.add(:endtrns)
|
67
|
+
@iif = @rs.to_iif
|
68
|
+
end
|
69
|
+
|
70
|
+
should "contain 4 rows of iif data" do
|
71
|
+
assert_equal 4, @iif.size
|
72
|
+
end
|
73
|
+
|
74
|
+
should "contain two headers and two data rows" do
|
75
|
+
%w{ !TRNS !ENDTRNS TRNS ENDTRNS }.each do |row_type|
|
76
|
+
row = @iif.shift
|
77
|
+
assert row.start_with?(row_type), "#{row} should start #{row_type}"
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/test/test_rows.rb
ADDED
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'shoulda'
|
3
|
+
require 'simple_iif/rows'
|
4
|
+
|
5
|
+
include SimpleIif
|
6
|
+
|
7
|
+
class TestRows < Test::Unit::TestCase
|
8
|
+
|
9
|
+
REQUIRED_VENDOR_ATTRS = {
|
10
|
+
name: "A-00001-9",
|
11
|
+
printas: "Thomas Consulting",
|
12
|
+
addr1: "123 Main St",
|
13
|
+
addr2: "Lewisville",
|
14
|
+
vtype: "Author",
|
15
|
+
firstname: "Dave",
|
16
|
+
lastname: "Thomas",
|
17
|
+
:"1099" => "Y"
|
18
|
+
}
|
19
|
+
|
20
|
+
context "Creating an unknown row type" do
|
21
|
+
should "raise an exception" do
|
22
|
+
assert_raises(RuntimeError) do
|
23
|
+
Rows.for("WIBBLE")
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "Creating an empty vendor row" do
|
29
|
+
should "raise an exception because some fields are missing" do
|
30
|
+
assert_raises(RuntimeError) do
|
31
|
+
Rows.for("VEND")
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "Creating a vendor with all required fields" do
|
37
|
+
setup do
|
38
|
+
@vendor = Rows.for(:vend, REQUIRED_VENDOR_ATTRS)
|
39
|
+
end
|
40
|
+
|
41
|
+
should "succeed" do
|
42
|
+
assert true
|
43
|
+
end
|
44
|
+
|
45
|
+
should "set all the fields" do
|
46
|
+
REQUIRED_VENDOR_ATTRS.each do |k, v|
|
47
|
+
assert_equal v, @vendor.data[k.to_s.upcase]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
should "only have the given fields" do
|
52
|
+
assert_equal REQUIRED_VENDOR_ATTRS.size, @vendor.data.size
|
53
|
+
end
|
54
|
+
|
55
|
+
should "have the correct headers" do
|
56
|
+
assert_equal %w{ !VEND 1099 ADDR1 ADDR2 FIRSTNAME LASTNAME NAME PRINTAS VTYPE}, @vendor.headers
|
57
|
+
end
|
58
|
+
|
59
|
+
should "have the correct values" do
|
60
|
+
assert_equal %w{ VEND Y 123\ Main\ St Lewisville Dave Thomas A-00001-9 Thomas\ Consulting Author}, @vendor.values
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
context "creaiting a vendor with required fields but also with an invalid field" do
|
65
|
+
should "raise an exception" do
|
66
|
+
assert_raises(RuntimeError) do
|
67
|
+
Rows.for(:vend, REQUIRED_VENDOR_ATTRS.merge(invalid: 123))
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context "creaiting a vendor with required fields and with a valid field" do
|
73
|
+
setup do
|
74
|
+
@vendor = Rows.for(:vend, REQUIRED_VENDOR_ATTRS.merge(taxid: 123))
|
75
|
+
end
|
76
|
+
|
77
|
+
should "pass the valid field through" do
|
78
|
+
assert @vendor.headers.include?("TAXID")
|
79
|
+
assert @vendor.values.include?(123)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
end
|
metadata
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: simple_iif
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Dave Thomas
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-10-12 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: A simple library to assist in the handling of Quickbooks IIF files
|
15
|
+
email:
|
16
|
+
- dave@pragprog.com
|
17
|
+
executables: []
|
18
|
+
extensions: []
|
19
|
+
extra_rdoc_files: []
|
20
|
+
files:
|
21
|
+
- .gitignore
|
22
|
+
- Gemfile
|
23
|
+
- LICENSE
|
24
|
+
- README.md
|
25
|
+
- Rakefile
|
26
|
+
- lib/simple_iif.rb
|
27
|
+
- lib/simple_iif/.DS_Store
|
28
|
+
- lib/simple_iif/row_sequence.rb
|
29
|
+
- lib/simple_iif/rows.rb
|
30
|
+
- lib/simple_iif/rows/endtrans.rb
|
31
|
+
- lib/simple_iif/rows/spl.rb
|
32
|
+
- lib/simple_iif/rows/trans.rb
|
33
|
+
- lib/simple_iif/rows/vend.rb
|
34
|
+
- lib/simple_iif/version.rb
|
35
|
+
- simple_iif.gemspec
|
36
|
+
- test/test_row_sequence.rb
|
37
|
+
- test/test_rows.rb
|
38
|
+
homepage: ''
|
39
|
+
licenses: []
|
40
|
+
post_install_message:
|
41
|
+
rdoc_options: []
|
42
|
+
require_paths:
|
43
|
+
- lib
|
44
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
45
|
+
none: false
|
46
|
+
requirements:
|
47
|
+
- - ! '>='
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: '0'
|
50
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
51
|
+
none: false
|
52
|
+
requirements:
|
53
|
+
- - ! '>='
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
requirements: []
|
57
|
+
rubyforge_project:
|
58
|
+
rubygems_version: 1.8.24
|
59
|
+
signing_key:
|
60
|
+
specification_version: 3
|
61
|
+
summary: A simple library to assist in the handling of Quickbooks IIF files
|
62
|
+
test_files:
|
63
|
+
- test/test_row_sequence.rb
|
64
|
+
- test/test_rows.rb
|