invoicing 0.2.0 → 0.2.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.
- data.tar.gz.sig +0 -0
- data/History.txt +10 -0
- data/README.rdoc +3 -0
- data/Rakefile +10 -4
- data/lib/invoicing.rb +3 -0
- data/lib/invoicing/countries/uk.rb +15 -3
- data/lib/invoicing/ledger_item.rb +21 -6
- data/lib/invoicing/ledger_item/render_html.rb +2 -1
- data/lib/invoicing/ledger_item/render_ubl.rb +15 -4
- data/lib/invoicing/line_item.rb +9 -0
- data/lib/invoicing/tax_rate.rb +13 -0
- data/lib/invoicing/version.rb +1 -1
- data/test/connection_adapter_ext_test.rb +13 -5
- data/test/ledger_item_test.rb +13 -3
- data/test/line_item_test.rb +2 -2
- data/test/ref-output/creditnote3.html +1 -1
- data/test/render_html_test.rb +1 -0
- data/test/render_ubl_test.rb +16 -4
- data/test/test_helper.rb +29 -5
- metadata +6 -7
- metadata.gz.sig +4 -3
data.tar.gz.sig
CHANGED
Binary file
|
data/History.txt
CHANGED
@@ -1,3 +1,13 @@
|
|
1
|
+
== 0.2.1
|
2
|
+
|
3
|
+
* 2 minor enhancements:
|
4
|
+
* Added option to LedgerItem#account_summary which enables inclusion of open/pending
|
5
|
+
ledger items in the summary
|
6
|
+
* Improved robustness and documentation for test suite
|
7
|
+
* 2 bugfixes:
|
8
|
+
* Compatibility with recent versions of ActiveRecord
|
9
|
+
* Cleaned up unnecessary gem dependencies (mocha, uuid)
|
10
|
+
|
1
11
|
== 0.2.0 2009-04-20
|
2
12
|
|
3
13
|
* 4 major enhancements:
|
data/README.rdoc
CHANGED
@@ -20,6 +20,9 @@ Please see {the website}[http://ept.github.com/invoicing/] for an introduction
|
|
20
20
|
to using Invoicing, and check the
|
21
21
|
{API reference}[http://invoicing.rubyforge.org/doc/] for in-depth details.
|
22
22
|
|
23
|
+
If you're interested in contributing to the invoicing gem itself, please see the file
|
24
|
+
{HACKING.md}[http://github.com/ept/invoicing/blob/master/HACKING.md].
|
25
|
+
|
23
26
|
== FEATURES
|
24
27
|
|
25
28
|
* TODO
|
data/Rakefile
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
%w[rubygems rake rake/clean fileutils newgem rubigen].each { |f| require f }
|
1
|
+
%w[rubygems rake rake/clean fileutils newgem rubigen hoe].each { |f| require f }
|
2
2
|
require File.dirname(__FILE__) + '/lib/invoicing'
|
3
3
|
|
4
4
|
# Hoe calls Ruby with the "-w" set by default; unfortunately, ActiveRecord (at version 2.2.2
|
@@ -6,16 +6,21 @@ require File.dirname(__FILE__) + '/lib/invoicing'
|
|
6
6
|
# the output. Comment out the following four lines to see those warnings.
|
7
7
|
class Hoe
|
8
8
|
RUBY_FLAGS = ENV['RUBY_FLAGS'] || "-I#{%w(lib test).join(File::PATH_SEPARATOR)}" +
|
9
|
-
(RUBY_DEBUG ? " #{RUBY_DEBUG}" : '')
|
9
|
+
((defined?(RUBY_DEBUG) && RUBY_DEBUG) ? " #{RUBY_DEBUG}" : '')
|
10
10
|
end
|
11
11
|
|
12
12
|
# Generate all the Rake tasks
|
13
13
|
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
14
|
-
$hoe = Hoe.
|
15
|
-
p.
|
14
|
+
$hoe = Hoe.spec 'invoicing' do |p|
|
15
|
+
p.version = Invoicing::VERSION
|
16
|
+
p.developer 'Martin Kleppmann', 'rubyforge@eptcomputing.com'
|
17
|
+
|
18
|
+
p.summary = p.paragraphs_of('README.rdoc', 3).join
|
19
|
+
p.description = p.paragraphs_of('README.rdoc', 3..5).join("\n\n")
|
16
20
|
p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
|
17
21
|
p.post_install_message = 'PostInstall.txt'
|
18
22
|
p.rubyforge_name = p.name
|
23
|
+
|
19
24
|
p.extra_deps = [
|
20
25
|
['activerecord', '>= 2.1.0'],
|
21
26
|
['builder', '>= 2.0']
|
@@ -28,6 +33,7 @@ $hoe = Hoe.new('invoicing', Invoicing::VERSION) do |p|
|
|
28
33
|
p.test_globs = %w[test/*_test.rb] # do not include test/models/*.rb
|
29
34
|
p.clean_globs |= %w[**/.DS_Store tmp *.log coverage]
|
30
35
|
p.rsync_args = '-av --delete --ignore-errors'
|
36
|
+
p.remote_rdoc_dir = 'doc'
|
31
37
|
end
|
32
38
|
|
33
39
|
require 'newgem/tasks' # load /tasks/*.rake
|
data/lib/invoicing.rb
CHANGED
@@ -3,12 +3,24 @@ module Invoicing
|
|
3
3
|
module UK
|
4
4
|
# Extremely simplistic implementation of UK VAT. This needs to be fixed.
|
5
5
|
class VAT
|
6
|
+
def tax_rate(params)
|
7
|
+
params[:model_object].send(:tax_rate)
|
8
|
+
end
|
9
|
+
|
10
|
+
def tax_factor(params)
|
11
|
+
BigDecimal('1') + tax_rate(params).rate
|
12
|
+
end
|
13
|
+
|
14
|
+
def tax_percent(params)
|
15
|
+
BigDecimal('100') * tax_rate(params).rate
|
16
|
+
end
|
17
|
+
|
6
18
|
def apply_tax(params)
|
7
|
-
params[:value] *
|
19
|
+
params[:value] * tax_factor(params)
|
8
20
|
end
|
9
21
|
|
10
22
|
def remove_tax(params)
|
11
|
-
params[:value] /
|
23
|
+
params[:value] / tax_factor(params)
|
12
24
|
end
|
13
25
|
|
14
26
|
def tax_info(params)
|
@@ -16,7 +28,7 @@ module Invoicing
|
|
16
28
|
end
|
17
29
|
|
18
30
|
def tax_details(params)
|
19
|
-
"(including VAT at
|
31
|
+
"(including VAT at #{tax_percent(params).to_s}%)"
|
20
32
|
end
|
21
33
|
end
|
22
34
|
end
|
@@ -430,6 +430,8 @@ module Invoicing
|
|
430
430
|
# Make sure ledger_item association is assigned -- the CurrencyValue
|
431
431
|
# getters depend on it to fetch the currency
|
432
432
|
info.set(line, :ledger_item, self)
|
433
|
+
line.valid? # Ensure any before_validation hooks are called
|
434
|
+
|
433
435
|
net_amount = info.get(line, :net_amount)
|
434
436
|
tax_amount = info.get(line, :tax_amount)
|
435
437
|
net_total += net_amount unless net_amount.nil?
|
@@ -615,7 +617,13 @@ module Invoicing
|
|
615
617
|
#
|
616
618
|
# If +other_id+ is +nil+, this method aggregates the accounts of +self_id+ with *all* other
|
617
619
|
# parties.
|
618
|
-
|
620
|
+
#
|
621
|
+
# Also accepts options:
|
622
|
+
#
|
623
|
+
# <tt>:with_status</tt>:: List of ledger item status strings; only ledger items whose status
|
624
|
+
# is one of these will be taken into account. Default:
|
625
|
+
# <tt>["closed", "cleared"]</tt>.
|
626
|
+
def account_summary(self_id, other_id=nil, options={})
|
619
627
|
info = ledger_item_class_info
|
620
628
|
self_id = self_id.to_i
|
621
629
|
other_id = [nil, ''].include?(other_id) ? nil : other_id.to_i
|
@@ -623,7 +631,7 @@ module Invoicing
|
|
623
631
|
if other_id.nil?
|
624
632
|
result = {}
|
625
633
|
# Sum over all others, grouped by currency
|
626
|
-
account_summaries(self_id).each_pair do |other_id, hash|
|
634
|
+
account_summaries(self_id, options).each_pair do |other_id, hash|
|
627
635
|
hash.each_pair do |currency, summary|
|
628
636
|
if result[currency]
|
629
637
|
result[currency] += summary
|
@@ -638,7 +646,7 @@ module Invoicing
|
|
638
646
|
conditions = {info.method(:sender_id) => [self_id, other_id],
|
639
647
|
info.method(:recipient_id) => [self_id, other_id]}
|
640
648
|
with_scope(:find => {:conditions => conditions}) do
|
641
|
-
account_summaries(self_id)[other_id] || {}
|
649
|
+
account_summaries(self_id, options)[other_id] || {}
|
642
650
|
end
|
643
651
|
end
|
644
652
|
end
|
@@ -661,7 +669,13 @@ module Invoicing
|
|
661
669
|
# q3_2008 = ['issue_date >= ? AND issue_date < ?', DateTime.parse('2008-07-01'), DateTime.parse('2008-10-01')]
|
662
670
|
# LedgerItem.scoped(:conditions => q3_2008).account_summaries(1)
|
663
671
|
#
|
664
|
-
|
672
|
+
#
|
673
|
+
# Also accepts options:
|
674
|
+
#
|
675
|
+
# <tt>:with_status</tt>:: List of ledger item status strings; only ledger items whose status
|
676
|
+
# is one of these will be taken into account. Default:
|
677
|
+
# <tt>["closed", "cleared"]</tt>.
|
678
|
+
def account_summaries(self_id, options={})
|
665
679
|
info = ledger_item_class_info
|
666
680
|
ext = Invoicing::ConnectionAdapterExt
|
667
681
|
scope = scope(:find)
|
@@ -681,8 +695,9 @@ module Invoicing
|
|
681
695
|
sender_is_self = merge_conditions({info.method(:sender_id) => self_id})
|
682
696
|
recipient_is_self = merge_conditions({info.method(:recipient_id) => self_id})
|
683
697
|
other_id_column = ext.conditional_function(sender_is_self, cols[:recipient_id], cols[:sender_id])
|
684
|
-
|
685
|
-
|
698
|
+
accept_status = sanitize_sql_hash_for_conditions(info.method(:status) => (options[:with_status] || %w(closed cleared)))
|
699
|
+
filter_conditions = "#{accept_status} AND (#{sender_is_self} OR #{recipient_is_self})"
|
700
|
+
|
686
701
|
sql = "SELECT #{other_id_column} AS other_id, #{cols[:currency]} AS currency, " +
|
687
702
|
"SUM(#{ext.conditional_function(debit_when_sent, cols[:total_amount], 0)}) AS sales, " +
|
688
703
|
"SUM(#{ext.conditional_function(debit_when_received, cols[:total_amount], 0)}) AS purchase_payments, " +
|
@@ -90,7 +90,7 @@ module Invoicing
|
|
90
90
|
invoice.cbc :ID, identifier
|
91
91
|
invoice.cbc :UUID, uuid if uuid
|
92
92
|
|
93
|
-
issue_date_formatted, issue_time_formatted = (issue_date || Time.now)
|
93
|
+
issue_date_formatted, issue_time_formatted = date_and_time(issue_date || Time.now)
|
94
94
|
invoice.cbc :IssueDate, issue_date_formatted
|
95
95
|
invoice.cbc :IssueTime, issue_time_formatted
|
96
96
|
|
@@ -173,8 +173,8 @@ module Invoicing
|
|
173
173
|
# <cbc:EndDate>2008-07-02</cbc:EndDate>
|
174
174
|
# <cbc:EndTime>01:02:03+02:00</cbc:EndTime>
|
175
175
|
def build_period(xml, start_datetime, end_datetime)
|
176
|
-
start_date, start_time = start_datetime
|
177
|
-
end_date, end_time = end_datetime
|
176
|
+
start_date, start_time = date_and_time(start_datetime)
|
177
|
+
end_date, end_time = date_and_time(end_datetime)
|
178
178
|
xml.cbc :StartDate, start_date
|
179
179
|
xml.cbc :StartTime, start_time
|
180
180
|
xml.cbc :EndDate, end_date
|
@@ -247,7 +247,10 @@ module Invoicing
|
|
247
247
|
quantity_tag = [:Invoice, :SelfBilledInvoice].include?(doc_type) ? :InvoicedQuantity : :CreditedQuantity
|
248
248
|
invoice_line.cbc quantity_tag, quantity_of(line_item) if quantity_of(line_item)
|
249
249
|
invoice_line.cbc :LineExtensionAmount, (factor*net_amount_of(line_item)).to_s, :currencyID => currency
|
250
|
-
|
250
|
+
if tax_point_of(line_item)
|
251
|
+
tax_point_date, tax_point_time = date_and_time(tax_point_of(line_item))
|
252
|
+
invoice_line.cbc :TaxPointDate, tax_point_date
|
253
|
+
end
|
251
254
|
|
252
255
|
invoice_line.cac :TaxTotal do |tax_total|
|
253
256
|
tax_total.cbc :TaxAmount, (factor*tax_amount_of(line_item)).to_s, :currencyID => currency
|
@@ -263,6 +266,14 @@ module Invoicing
|
|
263
266
|
|
264
267
|
#cac:Price
|
265
268
|
end
|
269
|
+
|
270
|
+
private
|
271
|
+
|
272
|
+
# Returns an array of two strings, <tt>[date, time]</tt> in the format specified by UBL,
|
273
|
+
# for a given datetime value.
|
274
|
+
def date_and_time(value)
|
275
|
+
value.in_time_zone(Time.zone || 'Etc/UTC').xmlschema.split('T')
|
276
|
+
end
|
266
277
|
end
|
267
278
|
end
|
268
279
|
end
|
data/lib/invoicing/line_item.rb
CHANGED
@@ -149,6 +149,8 @@ module Invoicing
|
|
149
149
|
# Set the 'amount' columns to act as currency values
|
150
150
|
acts_as_currency_value(info.method(:net_amount), info.method(:tax_amount))
|
151
151
|
|
152
|
+
before_validation :calculate_tax_amount
|
153
|
+
|
152
154
|
extend Invoicing::FindSubclasses
|
153
155
|
|
154
156
|
# Dynamically created named scopes
|
@@ -192,6 +194,11 @@ module Invoicing
|
|
192
194
|
ledger_item.send(:ledger_item_class_info).get(ledger_item, :currency)
|
193
195
|
end
|
194
196
|
|
197
|
+
def calculate_tax_amount
|
198
|
+
return unless respond_to? :net_amount_taxed
|
199
|
+
self.tax_amount = net_amount_taxed - net_amount
|
200
|
+
end
|
201
|
+
|
195
202
|
# The sum of +net_amount+ and +tax_amount+.
|
196
203
|
def gross_amount
|
197
204
|
net_amount = line_item_class_info.get(self, :net_amount)
|
@@ -212,6 +219,8 @@ module Invoicing
|
|
212
219
|
raise RuntimeError, "You need to define an association like 'belongs_to :ledger_item' on #{self.class.name}. If you " +
|
213
220
|
"have defined the association with a different name, pass the option :ledger_item => :your_association_name to " +
|
214
221
|
"acts_as_line_item."
|
222
|
+
elsif method_name =~ /^amount/
|
223
|
+
send("net_#{method_name}", *args)
|
215
224
|
else
|
216
225
|
super
|
217
226
|
end
|
data/lib/invoicing/tax_rate.rb
CHANGED
@@ -2,8 +2,21 @@ module Invoicing
|
|
2
2
|
module TaxRate
|
3
3
|
module ActMethods
|
4
4
|
def acts_as_tax_rate(*args)
|
5
|
+
Invoicing::ClassInfo.acts_as(Invoicing::TaxRate, self, args)
|
6
|
+
info = tax_rate_class_info
|
5
7
|
|
8
|
+
if info.previous_info.nil? # Called for the first time?
|
9
|
+
# Import TimeDependent functionality
|
10
|
+
acts_as_time_dependent :value => :rate
|
11
|
+
end
|
6
12
|
end
|
7
13
|
end
|
14
|
+
|
15
|
+
# Stores state in the ActiveRecord class object
|
16
|
+
class ClassInfo < Invoicing::ClassInfo::Base #:nodoc:
|
17
|
+
def initialize(model_class, previous_info, args)
|
18
|
+
super
|
19
|
+
end
|
20
|
+
end
|
8
21
|
end
|
9
22
|
end
|
data/lib/invoicing/version.rb
CHANGED
@@ -9,11 +9,19 @@ class ConnectionAdapterExtTest < Test::Unit::TestCase
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def using_database(database_type)
|
12
|
-
|
13
|
-
|
12
|
+
if database_type.to_sym == database_used_for_testing
|
13
|
+
# If the test is for the main database type of this test suite, just run it
|
14
14
|
yield
|
15
|
-
|
16
|
-
|
15
|
+
|
16
|
+
elsif test_in_all_databases
|
17
|
+
# Run the test having connected to the requested database type, or skip it
|
18
|
+
# if we're not trying to test all database types
|
19
|
+
begin
|
20
|
+
ActiveRecord::Base.establish_connection(TEST_DB_CONFIG[database_type.to_sym])
|
21
|
+
yield
|
22
|
+
ensure
|
23
|
+
connect_to_testing_database
|
24
|
+
end
|
17
25
|
end
|
18
26
|
end
|
19
27
|
|
@@ -68,4 +76,4 @@ class ConnectionAdapterExtTest < Test::Unit::TestCase
|
|
68
76
|
end
|
69
77
|
end
|
70
78
|
|
71
|
-
end
|
79
|
+
end
|
data/test/ledger_item_test.rb
CHANGED
@@ -218,11 +218,11 @@ class LedgerItemTest < Test::Unit::TestCase
|
|
218
218
|
|
219
219
|
def test_uuid_gem_not_present
|
220
220
|
begin
|
221
|
-
real_uuid = Object.send(:remove_const, :UUID)
|
221
|
+
real_uuid = Object.send(:remove_const, :UUID) rescue nil
|
222
222
|
UUIDNotPresentLedgerItem.acts_as_ledger_item(LedgerItemMethods::RENAMED_METHODS)
|
223
223
|
assert_nil UUIDNotPresentLedgerItem.new.get_class_info.uuid_generator
|
224
224
|
ensure
|
225
|
-
Object.send(:const_set, :UUID, real_uuid)
|
225
|
+
Object.send(:const_set, :UUID, real_uuid) unless real_uuid.nil?
|
226
226
|
end
|
227
227
|
end
|
228
228
|
|
@@ -362,7 +362,17 @@ class LedgerItemTest < Test::Unit::TestCase
|
|
362
362
|
assert_equal BigDecimal('0.00'), summary[:GBP].purchase_payments
|
363
363
|
assert_equal BigDecimal('-666807.63'), summary[:GBP].balance
|
364
364
|
end
|
365
|
-
|
365
|
+
|
366
|
+
def test_account_summary_with_include_open_option
|
367
|
+
summary = MyLedgerItem.account_summary(1, nil, :with_status => %w(open closed cleared))
|
368
|
+
assert_equal [:GBP], summary.keys
|
369
|
+
assert_equal BigDecimal('269.00'), summary[:GBP].sales
|
370
|
+
assert_equal BigDecimal('666808.63'), summary[:GBP].purchases
|
371
|
+
assert_equal BigDecimal('256.50'), summary[:GBP].sale_receipts
|
372
|
+
assert_equal BigDecimal('0.00'), summary[:GBP].purchase_payments
|
373
|
+
assert_equal BigDecimal('-666796.13'), summary[:GBP].balance
|
374
|
+
end
|
375
|
+
|
366
376
|
def test_account_summary_to_s
|
367
377
|
assert_equal "sales = £257.50; purchases = £666,808.63; sale_receipts = £256.50; " +
|
368
378
|
"purchase_payments = £0.00; balance = −£666,807.63", MyLedgerItem.account_summary(1)[:GBP].to_s
|
data/test/line_item_test.rb
CHANGED
@@ -99,11 +99,11 @@ class LineItemTest < Test::Unit::TestCase
|
|
99
99
|
|
100
100
|
def test_uuid_gem_not_present
|
101
101
|
begin
|
102
|
-
real_uuid = Object.send(:remove_const, :UUID)
|
102
|
+
real_uuid = Object.send(:remove_const, :UUID) rescue nil
|
103
103
|
UUIDNotPresentLineItem.acts_as_line_item(LineItemMethods::RENAMED_METHODS)
|
104
104
|
assert_nil UUIDNotPresentLineItem.new.get_class_info.uuid_generator
|
105
105
|
ensure
|
106
|
-
Object.send(:const_set, :UUID, real_uuid)
|
106
|
+
Object.send(:const_set, :UUID, real_uuid) unless real_uuid.nil?
|
107
107
|
end
|
108
108
|
end
|
109
109
|
|
data/test/render_html_test.rb
CHANGED
@@ -28,6 +28,7 @@ class RenderHTMLTest < Test::Unit::TestCase
|
|
28
28
|
expected[0] = "<h1>INVOICE</h1>"
|
29
29
|
expected[3] = " <th class=\"recipient\">Customer</th>"
|
30
30
|
expected[4] = " <th class=\"sender\">Supplier</th>"
|
31
|
+
expected[40] = " <th>INVOICE no.:</th>"
|
31
32
|
rendered = MyInvoice.find(1).render_html {|i|
|
32
33
|
i.invoice_label{ "INVOICE" }
|
33
34
|
i.sender_label "Supplier"
|
data/test/render_ubl_test.rb
CHANGED
@@ -7,20 +7,32 @@ class RenderUBLTest < Test::Unit::TestCase
|
|
7
7
|
def reference_output(filename)
|
8
8
|
IO.readlines(File.join(File.dirname(__FILE__), 'ref-output', filename)).join
|
9
9
|
end
|
10
|
-
|
10
|
+
|
11
|
+
# Compares two strings, each being a serialised XML document, while ignoring
|
12
|
+
# the order of attributes within elements.
|
13
|
+
# TODO: this could generate much nicer error messages on failure.
|
14
|
+
def assert_equivalent_xml(doc1, doc2)
|
15
|
+
doc1, doc2 = [doc1, doc2].map do |doc|
|
16
|
+
doc.gsub(/(<[^\s>]+\s+)([^>]+)(>)/) do |match|
|
17
|
+
$1.to_s + $2.to_s.split(/\s+/).sort.join(' ') + $3.to_s
|
18
|
+
end
|
19
|
+
end
|
20
|
+
assert_equal doc1, doc2
|
21
|
+
end
|
22
|
+
|
11
23
|
def test_render_ubl_invoice
|
12
|
-
|
24
|
+
assert_equivalent_xml reference_output('invoice1.xml'), MyInvoice.find(1).render_ubl
|
13
25
|
end
|
14
26
|
|
15
27
|
def test_render_ubl_self_billed_invoice
|
16
|
-
|
28
|
+
assert_equivalent_xml reference_output('invoice2.xml'), MyInvoice.find(2).render_ubl
|
17
29
|
end
|
18
30
|
|
19
31
|
def test_render_ubl_credit_note
|
20
32
|
#File.open(File.join(File.dirname(__FILE__), 'ref-output', 'debug3.xml'), 'w') do |f|
|
21
33
|
# f.syswrite(MyCreditNote.find(3).render_ubl)
|
22
34
|
#end
|
23
|
-
|
35
|
+
assert_equivalent_xml reference_output('creditnote3.xml'), MyCreditNote.find(3).render_ubl
|
24
36
|
end
|
25
37
|
|
26
38
|
def test_cannot_render_unknown_ledger_item_subtype
|
data/test/test_helper.rb
CHANGED
@@ -3,7 +3,6 @@ require 'rubygems'
|
|
3
3
|
require 'activerecord'
|
4
4
|
require 'activesupport'
|
5
5
|
require 'flexmock/test_unit'
|
6
|
-
require 'mocha'
|
7
6
|
|
8
7
|
$: << File.join(File.dirname(__FILE__), '..', 'lib')
|
9
8
|
|
@@ -11,20 +10,45 @@ ActiveSupport::Dependencies.load_paths << File.join(File.dirname(__FILE__), 'mod
|
|
11
10
|
|
12
11
|
require 'invoicing'
|
13
12
|
|
13
|
+
# Overridden by ../../config/database.yml if it exists.
|
14
14
|
TEST_DB_CONFIG = {
|
15
15
|
:postgresql => {:adapter => "postgresql", :host => "localhost", :database => "invoicing_test",
|
16
|
-
:username => "
|
16
|
+
:username => "invoicing", :password => "password"},
|
17
17
|
:mysql => {:adapter => "mysql", :host => "localhost", :database => "invoicing_test",
|
18
|
-
:username => "root", :password => ""}
|
19
|
-
:sqlite3 => {:adapter => "sqlite3", :database => Tempfile.new('invoicing_sqlite').path}
|
18
|
+
:username => "root", :password => ""}
|
20
19
|
}
|
20
|
+
TEST_DB_CONFIG_FILE = File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'config', 'database.yml'))
|
21
|
+
|
22
|
+
def database_used_for_testing
|
23
|
+
(ENV['DATABASE'] || :mysql).to_sym
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_in_all_databases
|
27
|
+
!!ENV['TEST_ALL_DATABASES']
|
28
|
+
end
|
21
29
|
|
22
30
|
def connect_to_testing_database
|
23
|
-
|
31
|
+
db_config = TEST_DB_CONFIG[database_used_for_testing]
|
32
|
+
db_config_from_file = false
|
33
|
+
|
34
|
+
if File.exists? TEST_DB_CONFIG_FILE
|
35
|
+
yaml = YAML::load File.open(TEST_DB_CONFIG_FILE)
|
36
|
+
if yaml && yaml['test'] && (yaml['test']['adapter'].to_s == database_used_for_testing.to_s)
|
37
|
+
db_config = yaml['test']
|
38
|
+
db_config_from_file = true
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
puts "Connecting to #{database_used_for_testing} with config #{db_config.inspect}" +
|
43
|
+
(db_config_from_file ? " from #{TEST_DB_CONFIG_FILE}" : "")
|
44
|
+
ActiveRecord::Base.establish_connection(db_config)
|
24
45
|
end
|
25
46
|
|
26
47
|
connect_to_testing_database
|
27
48
|
|
49
|
+
require 'setup'
|
50
|
+
|
51
|
+
|
28
52
|
ENV['TZ'] = 'Etc/UTC' # timezone of values in database
|
29
53
|
ActiveRecord::Base.default_timezone = :utc # timezone of created_at and updated_at
|
30
54
|
Time.zone = 'Etc/UTC' # timezone for output (when using Time#in_time_zone)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: invoicing
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Martin Kleppmann
|
@@ -30,7 +30,7 @@ cert_chain:
|
|
30
30
|
jT4Qh3sYJbvqWGFAQcuOIf4spvpNiA==
|
31
31
|
-----END CERTIFICATE-----
|
32
32
|
|
33
|
-
date: 2009-
|
33
|
+
date: 2009-08-26 00:00:00 +01:00
|
34
34
|
default_executable:
|
35
35
|
dependencies:
|
36
36
|
- !ruby/object:Gem::Dependency
|
@@ -71,7 +71,7 @@ dependencies:
|
|
71
71
|
requirements:
|
72
72
|
- - ">="
|
73
73
|
- !ruby/object:Gem::Version
|
74
|
-
version:
|
74
|
+
version: 2.3.2
|
75
75
|
version:
|
76
76
|
description: This is a framework for generating and displaying invoices (ideal for commercial Rails apps). It allows for flexible business logic; provides tools for tax handling, commission calculation etc. It aims to be both developer-friendly and accountant-friendly. The Ruby Invoicing Framework is based on {ActiveRecord}[http://api.rubyonrails.org/classes/ActiveRecord/Base.html]. Please see {the website}[http://ept.github.com/invoicing/] for an introduction to using Invoicing, and check the {API reference}[http://invoicing.rubyforge.org/doc/] for in-depth details.
|
77
77
|
email:
|
@@ -84,7 +84,6 @@ extra_rdoc_files:
|
|
84
84
|
- History.txt
|
85
85
|
- Manifest.txt
|
86
86
|
- PostInstall.txt
|
87
|
-
- README.rdoc
|
88
87
|
files:
|
89
88
|
- History.txt
|
90
89
|
- LICENSE
|
@@ -149,11 +148,11 @@ files:
|
|
149
148
|
- test/test_helper.rb
|
150
149
|
- test/time_dependent_test.rb
|
151
150
|
has_rdoc: true
|
152
|
-
homepage:
|
151
|
+
homepage:
|
153
152
|
post_install_message: PostInstall.txt
|
154
153
|
rdoc_options:
|
155
154
|
- --main
|
156
|
-
- README.
|
155
|
+
- README.txt
|
157
156
|
require_paths:
|
158
157
|
- lib
|
159
158
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -174,7 +173,7 @@ rubyforge_project: invoicing
|
|
174
173
|
rubygems_version: 1.3.1
|
175
174
|
signing_key:
|
176
175
|
specification_version: 2
|
177
|
-
summary: This is a framework for generating and displaying invoices (ideal for commercial Rails apps)
|
176
|
+
summary: This is a framework for generating and displaying invoices (ideal for commercial Rails apps). It allows for flexible business logic; provides tools for tax handling, commission calculation etc. It aims to be both developer-friendly and accountant-friendly.
|
178
177
|
test_files:
|
179
178
|
- test/cached_record_test.rb
|
180
179
|
- test/class_info_test.rb
|
metadata.gz.sig
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
�
|
1
|
+
�9V��g贵��QV�
|
2
|
+
Ĺ���!�2ګ��iw���X��"�NBz�#��P��m�r%����iJ��e0wA���|��j���+=X.��v����_��%��bà
|
3
|
+
�MQ�����/����e��ْ�NQ�6[�m��5vc��$0�
|
4
|
+
Te�kX{%v���Җ|��P3��������(��oTYE�dg��و��ќK�7��h-HB� �ZH,ư��c����&Wx����5A���A�t7i}���
|