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 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.new('invoicing', Invoicing::VERSION) do |p|
15
- p.developer('Martin Kleppmann', 'rubyforge@eptcomputing.com')
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
@@ -1,3 +1,6 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
1
4
  require 'activerecord'
2
5
 
3
6
  require 'invoicing/class_info' # load first because other modules depend on this
@@ -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] * BigDecimal('1.15')
19
+ params[:value] * tax_factor(params)
8
20
  end
9
21
 
10
22
  def remove_tax(params)
11
- params[:value] / BigDecimal('1.15')
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 15%)"
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
- def account_summary(self_id, other_id=nil)
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
- def account_summaries(self_id)
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
- filter_conditions = "#{cols[:status]} IN ('closed','cleared') AND (#{sender_is_self} OR #{recipient_is_self})"
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, " +
@@ -190,7 +190,8 @@ module Invoicing
190
190
  end
191
191
 
192
192
  def default_identifier_label
193
- "Invoice no.:"
193
+ label = (factor == BigDecimal('-1')) ? invoke_credit_note_label : invoke_invoice_label
194
+ "#{label} no.:"
194
195
  end
195
196
 
196
197
  def default_issue_date_label
@@ -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).in_time_zone.xmlschema.split('T')
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.in_time_zone.xmlschema.split('T')
177
- end_date, end_time = end_datetime.in_time_zone.xmlschema.split('T')
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
- invoice_line.cbc :TaxPointDate, tax_point_of(line_item).in_time_zone.strftime('%Y-%m-%d') if tax_point_of(line_item)
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
@@ -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
@@ -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
@@ -2,7 +2,7 @@ module Invoicing
2
2
  module Version
3
3
  MAJOR = 0
4
4
  MINOR = 2
5
- BUILD = 0
5
+ BUILD = 1
6
6
 
7
7
  def to_a
8
8
  [MAJOR, MINOR, BUILD]
@@ -9,11 +9,19 @@ class ConnectionAdapterExtTest < Test::Unit::TestCase
9
9
  end
10
10
 
11
11
  def using_database(database_type)
12
- begin
13
- ActiveRecord::Base.establish_connection(TEST_DB_CONFIG[database_type.to_sym])
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
- ensure
16
- connect_to_testing_database
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
@@ -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
@@ -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
 
@@ -38,7 +38,7 @@
38
38
  </table>
39
39
  <table class="invoice metadata">
40
40
  <tr class="identifier">
41
- <th>Invoice no.:</th>
41
+ <th>Credit Note no.:</th>
42
42
  <td>putain!</td>
43
43
  </tr>
44
44
  <tr class="issue-date">
@@ -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"
@@ -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
- assert_equal reference_output('invoice1.xml'), MyInvoice.find(1).render_ubl
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
- assert_equal reference_output('invoice2.xml'), MyInvoice.find(2).render_ubl
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
- assert_equal reference_output('creditnote3.xml'), MyCreditNote.find(3).render_ubl
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 => "postgres", :password => ""},
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
- ActiveRecord::Base.establish_connection(TEST_DB_CONFIG[(ENV['DATABASE'] || :mysql).to_sym])
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.0
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-04-20 00:00:00 +01:00
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: 1.8.0
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: "{Ruby Invoicing Framework website}[http://ept.github.com/invoicing/]"
151
+ homepage:
153
152
  post_install_message: PostInstall.txt
154
153
  rdoc_options:
155
154
  - --main
156
- - README.rdoc
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
- � -T"Q�;�!�嬈�C��4�H�`=�s��g^�(�v�PD��aOe<�QY
2
- 3�i!f�\gA}������]:�:c��gܣ���y��S,�3m�.9R(�}Z� �4Ҿ�� ?N/�x_�����E#���s�O�9��)wC�מ�B�H�K=P6�J�%��z�>"?�ї#N)��P��w;W�_�ѯ���`z��}��Cv
3
- �hJ�ڐ��V��w���Ac����$Uۘ}��ޮ��v&ͭ�y"
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}���