invoicing 0.2.1 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +1 -0
  3. data/README.md +57 -0
  4. data/Rakefile +16 -37
  5. data/lib/invoicing.rb +20 -10
  6. data/lib/invoicing/cached_record.rb +9 -6
  7. data/lib/invoicing/class_info.rb +34 -34
  8. data/lib/invoicing/connection_adapter_ext.rb +4 -4
  9. data/lib/invoicing/countries/uk.rb +6 -6
  10. data/lib/invoicing/currency_value.rb +39 -32
  11. data/lib/invoicing/find_subclasses.rb +40 -15
  12. data/lib/invoicing/ledger_item.rb +166 -145
  13. data/lib/invoicing/ledger_item/pdf_generator.rb +108 -0
  14. data/lib/invoicing/ledger_item/render_html.rb +76 -73
  15. data/lib/invoicing/ledger_item/render_ubl.rb +37 -35
  16. data/lib/invoicing/line_item.rb +43 -38
  17. data/lib/invoicing/price.rb +1 -1
  18. data/lib/invoicing/tax_rate.rb +3 -6
  19. data/lib/invoicing/taxable.rb +37 -32
  20. data/lib/invoicing/time_dependent.rb +40 -40
  21. data/lib/invoicing/version.rb +4 -4
  22. data/lib/rails/generators/invoicing/invoicing_generator.rb +14 -0
  23. data/lib/rails/generators/invoicing/ledger_item/ledger_item_generator.rb +17 -0
  24. data/lib/rails/generators/invoicing/ledger_item/templates/migration.rb +25 -0
  25. data/lib/rails/generators/invoicing/ledger_item/templates/model.rb +5 -0
  26. data/lib/rails/generators/invoicing/line_item/line_item_generator.rb +17 -0
  27. data/lib/rails/generators/invoicing/line_item/templates/migration.rb +20 -0
  28. data/lib/rails/generators/invoicing/line_item/templates/model.rb +5 -0
  29. data/lib/rails/generators/invoicing/tax_rate/tax_rate_generator.rb +17 -0
  30. data/lib/rails/generators/invoicing/tax_rate/templates/migration.rb +14 -0
  31. data/lib/rails/generators/invoicing/tax_rate/templates/model.rb +3 -0
  32. metadata +110 -153
  33. data.tar.gz.sig +0 -1
  34. data/History.txt +0 -31
  35. data/Manifest.txt +0 -62
  36. data/PostInstall.txt +0 -10
  37. data/README.rdoc +0 -58
  38. data/script/console +0 -10
  39. data/script/destroy +0 -14
  40. data/script/generate +0 -14
  41. data/tasks/rcov.rake +0 -4
  42. data/test/cached_record_test.rb +0 -100
  43. data/test/class_info_test.rb +0 -253
  44. data/test/connection_adapter_ext_test.rb +0 -79
  45. data/test/currency_value_test.rb +0 -209
  46. data/test/find_subclasses_test.rb +0 -120
  47. data/test/fixtures/README +0 -7
  48. data/test/fixtures/cached_record.sql +0 -22
  49. data/test/fixtures/class_info.sql +0 -28
  50. data/test/fixtures/currency_value.sql +0 -29
  51. data/test/fixtures/find_subclasses.sql +0 -43
  52. data/test/fixtures/ledger_item.sql +0 -39
  53. data/test/fixtures/line_item.sql +0 -33
  54. data/test/fixtures/price.sql +0 -4
  55. data/test/fixtures/tax_rate.sql +0 -4
  56. data/test/fixtures/taxable.sql +0 -14
  57. data/test/fixtures/time_dependent.sql +0 -35
  58. data/test/ledger_item_test.rb +0 -444
  59. data/test/line_item_test.rb +0 -139
  60. data/test/models/README +0 -4
  61. data/test/models/test_subclass_in_another_file.rb +0 -3
  62. data/test/models/test_subclass_not_in_database.rb +0 -6
  63. data/test/price_test.rb +0 -9
  64. data/test/ref-output/creditnote3.html +0 -82
  65. data/test/ref-output/creditnote3.xml +0 -89
  66. data/test/ref-output/invoice1.html +0 -93
  67. data/test/ref-output/invoice1.xml +0 -111
  68. data/test/ref-output/invoice2.html +0 -86
  69. data/test/ref-output/invoice2.xml +0 -98
  70. data/test/ref-output/invoice_null.html +0 -36
  71. data/test/render_html_test.rb +0 -70
  72. data/test/render_ubl_test.rb +0 -44
  73. data/test/setup.rb +0 -37
  74. data/test/tax_rate_test.rb +0 -9
  75. data/test/taxable_test.rb +0 -180
  76. data/test/test_helper.rb +0 -72
  77. data/test/time_dependent_test.rb +0 -180
  78. metadata.gz.sig +0 -4
@@ -1,29 +0,0 @@
1
- DROP TABLE IF EXISTS currency_value_records;
2
-
3
- CREATE TABLE currency_value_records (
4
- id int primary key auto_increment,
5
- currency_code varchar(3),
6
- amount decimal(20,4),
7
- tax_amount decimal(20,4)
8
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
9
-
10
- INSERT INTO currency_value_records(id, currency_code, amount, tax_amount) values
11
- (1, 'GBP', 123.45, NULL),
12
- (2, 'EUR', 98765432, 0.02),
13
- (3, 'CNY', 5432, 0),
14
- (4, 'JPY', 8888, 123),
15
- (5, 'XXX', 123, NULL);
16
-
17
- ALTER SEQUENCE currency_value_records_id_seq start 1000;
18
-
19
-
20
- DROP TABLE IF EXISTS no_currency_column_records;
21
-
22
- CREATE TABLE no_currency_column_records (
23
- id int primary key auto_increment,
24
- amount decimal(20,4)
25
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
26
-
27
- INSERT INTO no_currency_column_records(id, amount) values(1, '95.15');
28
-
29
- ALTER SEQUENCE no_currency_column_records_id_seq start 1000;
@@ -1,43 +0,0 @@
1
- DROP TABLE IF EXISTS find_subclasses_records;
2
-
3
- CREATE TABLE find_subclasses_records (
4
- id int primary key auto_increment,
5
- value varchar(255),
6
- type_name varchar(255),
7
- associate_id int
8
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
9
-
10
- INSERT INTO find_subclasses_records(id, value, associate_id, type_name) values
11
- (1, 'Mooo!', 1, 'TestBaseclass'),
12
- (2, 'Baaa!', NULL, 'TestSubclass'),
13
- (3, 'Mooo!', NULL, 'TestSubSubclass'),
14
- (4, 'Baaa!', NULL, 'TestSubclassInAnotherFile'),
15
- (5, 'Mooo!', 1, 'TestModule::TestInsideModuleSubclass'),
16
- (6, 'Baaa!', 1, 'TestOutsideModuleSubSubclass');
17
-
18
- ALTER SEQUENCE find_subclasses_records_id_seq start 1000;
19
-
20
-
21
- DROP TABLE IF EXISTS find_subclasses_associates;
22
-
23
- CREATE TABLE find_subclasses_associates (
24
- id int primary key auto_increment,
25
- value varchar(255)
26
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
27
-
28
- INSERT INTO find_subclasses_associates (id, value) values(1, 'Cool stuff');
29
-
30
- ALTER SEQUENCE find_subclasses_associates_id_seq start 1000;
31
-
32
-
33
- DROP TABLE IF EXISTS find_subclasses_non_existent;
34
-
35
- CREATE TABLE find_subclasses_non_existent (
36
- id int primary key auto_increment,
37
- value varchar(255),
38
- type varchar(255)
39
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
40
-
41
- INSERT INTO find_subclasses_non_existent(id, value, type) values(1, 'Badger', 'SurelyThereIsNoClassWithThisName');
42
-
43
- ALTER SEQUENCE find_subclasses_non_existent_id_seq start 1000;
@@ -1,39 +0,0 @@
1
- DROP TABLE IF EXISTS ledger_item_records;
2
-
3
- CREATE TABLE ledger_item_records (
4
- id2 int primary key auto_increment,
5
- type2 varchar(255) not null,
6
- sender_id2 int,
7
- recipient_id2 int,
8
- identifier2 varchar(255),
9
- issue_date2 datetime,
10
- currency2 varchar(5),
11
- total_amount2 decimal(20,4),
12
- tax_amount2 decimal(20,4),
13
- status2 varchar(100),
14
- period_start2 datetime,
15
- period_end2 datetime,
16
- uuid2 varchar(40),
17
- due_date2 datetime,
18
- created_at datetime,
19
- updated_at datetime
20
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
21
-
22
-
23
- INSERT INTO ledger_item_records
24
- (id2, type2, sender_id2, recipient_id2, identifier2, issue_date2, currency2, total_amount2, tax_amount2, status2, period_start2, period_end2, uuid2, due_date2, created_at, updated_at) values
25
- (1, 'MyInvoice', 1, 2, '1', '2008-06-30', 'GBP', 315.00, 15.00, 'closed', '2008-06-01', '2008-07-01', '30f4f680-d1b9-012b-48a5-0017f22d32c0', '2008-07-30', '2008-06-02 12:34:00', '2008-07-01 00:00:00'),
26
- (2, 'InvoiceSubtype', 2, 1, '12-ASDF', '2009-01-01', 'GBP', 141.97, 18.52, 'closed', '2008-01-01', '2009-01-01', 'fe4d20a0-d1b9-012b-48a5-0017f22d32c0', '2009-01-31', '2008-12-25 00:00:00', '2008-12-26 00:00:00'),
27
- (3, 'MyCreditNote', 1, 2, 'putain!', '2008-07-13', 'GBP', -57.50, -7.50, 'closed', '2008-06-01', '2008-07-01', '671a05d0-d1ba-012b-48a5-0017f22d32c0', NULL, '2008-07-13 09:13:14', '2008-07-13 09:13:14'),
28
- (4, 'MyPayment', 1, 2, '14BC4E0F', '2008-07-06', 'GBP', 256.50, 0.00, 'cleared', NULL, NULL, 'cfdf2ae0-d1ba-012b-48a5-0017f22d32c0', NULL, '2008-07-06 01:02:03', '2008-07-06 02:03:04'),
29
- (5, 'MyLedgerItem', 2, 3, NULL, '2007-04-23', 'USD', 432.10, NULL, 'closed', NULL, NULL, 'f6d6a700-d1ae-012b-48a5-0017f22d32c0', '2011-02-27', '2008-01-01 00:00:00', '2008-01-01 00:00:00'),
30
- (6, 'CorporationTaxLiability', 4, 1, 'OMGWTFBBQ', '2009-01-01', 'GBP', 666666.66, NULL, 'closed', '2008-01-01', '2009-01-01', '7273c000-d1bb-012b-48a5-0017f22d32c0', '2009-04-23', '2009-01-23 00:00:00', '2009-01-23 00:00:00'),
31
- (7, 'MyPayment', 1, 2, 'nonsense', '2009-01-23', 'GBP', 1000000.00, 0.00, 'failed', NULL, NULL, 'af488310-d1bb-012b-48a5-0017f22d32c0', NULL, '2009-01-23 00:00:00', '2009-01-23 00:00:00'),
32
- (8, 'MyPayment', 1, 2, '1quid', '2008-12-23', 'GBP', 1.00, 0.00, 'pending', NULL, NULL, 'df733560-d1bb-012b-48a5-0017f22d32c0', NULL, '2009-12-23 00:00:00', '2009-12-23 00:00:00'),
33
- (9, 'MyInvoice', 1, 2, '9', '2009-01-23', 'GBP', 11.50, 1.50, 'open', '2009-01-01', '2008-02-01', 'e5b0dac0-d1bb-012b-48a5-0017f22d32c0', '2009-02-01', '2009-12-23 00:00:00', '2009-12-23 00:00:00'),
34
- (10,'MyInvoice', 1, 2, 'a la con', '2009-01-23', 'GBP', 432198.76, 4610.62, 'cancelled', '2008-12-01', '2009-01-01', 'eb167b10-d1bb-012b-48a5-0017f22d32c0', NULL, '2009-12-23 00:00:00', '2009-12-23 00:00:00'),
35
- (11,'MyInvoice', 1, 2, 'no_lines', '2009-01-24', 'GBP', NULL, NULL, 'closed', '2009-01-23', '2009-01-24', '9ed54a00-d99f-012b-592c-0017f22d32c0', '2009-01-25', '2009-01-24 23:59:59', '2009-01-24 23:59:59');
36
-
37
- -- Invoice 10 is set to not add up correctly; total_amount is 0.01 too little to test error handling
38
-
39
- ALTER SEQUENCE ledger_item_records_id2_seq start 1000;
@@ -1,33 +0,0 @@
1
- DROP TABLE IF EXISTS line_item_records;
2
-
3
- CREATE TABLE line_item_records (
4
- id2 int primary key auto_increment,
5
- type2 varchar(255),
6
- ledger_item_id2 int not null,
7
- net_amount2 decimal(20,4),
8
- tax_amount2 decimal(20,4),
9
- uuid2 varchar(40),
10
- tax_point2 datetime,
11
- tax_rate_id2 int,
12
- price_id2 int,
13
- quantity2 decimal(10,5),
14
- creator_id2 int,
15
- created_at datetime,
16
- updated_at datetime
17
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
18
-
19
-
20
- -- Can you spot which make of computer I have?
21
-
22
- INSERT INTO line_item_records
23
- (id2, type2, ledger_item_id2, net_amount2, tax_amount2, uuid2, tax_point2, tax_rate_id2, price_id2, quantity2, creator_id2, created_at, updated_at) values
24
- (1, 'SuperLineItem', 1, 100.00, 15.00, '0cc659f0-cfac-012b-481d-0017f22d32c0', '2008-06-30', 1, 1, 1, 42, '2008-06-30 12:34:56', '2008-06-30 12:34:56'),
25
- (2, 'SubLineItem', 1, 200.00, 0, '0cc65e20-cfac-012b-481d-0017f22d32c0', '2008-06-25', 2, 2, 4, 42, '2008-06-30 21:43:56', '2008-06-30 21:43:56'),
26
- (3, 'OtherLineItem', 2, 123.45, 18.52, '0cc66060-cfac-012b-481d-0017f22d32c0', '2009-01-01', 1, NULL, 1, 43, '2008-12-25 00:00:00', '2008-12-26 00:00:00'),
27
- (4, 'UntaxedLineItem', 5, 432.10, NULL, '0cc662a0-cfac-012b-481d-0017f22d32c0', '2007-04-23', NULL, 3, NULL, 99, '2007-04-03 12:34:00', '2007-04-03 12:34:00'),
28
- (5, 'SuperLineItem', 3, -50.00, -7.50, 'eab28cf0-d1b4-012b-48a5-0017f22d32c0', '2008-07-13', 1, 1, 0.5, 42, '2008-07-13 09:13:14', '2008-07-13 09:13:14'),
29
- (6, 'OtherLineItem', 6, 666666.66, NULL, 'b5e66b50-d1b9-012b-48a5-0017f22d32c0', '2009-01-01', 3, NULL, 0, 666, '2009-01-23 00:00:00', '2009-01-23 00:00:00'),
30
- (7, 'SubLineItem', 9, 10.00, 1.50, '6f362040-d1be-012b-48a5-0017f22d32c0', '2009-01-31', 1, 1, 0.1, NULL, '2009-12-23 00:00:00', '2009-12-23 00:00:00'),
31
- (8, 'SubLineItem', 10, 427588.15, 4610.62, '3d12c020-d1bf-012b-48a5-0017f22d32c0', '2009-01-31', NULL, NULL, NULL, 42, '2009-12-23 00:00:00', '2009-12-23 00:00:00');
32
-
33
- ALTER SEQUENCE line_item_records_id2_seq start 1000;
@@ -1,4 +0,0 @@
1
- -- For consistency with line_item.sql:
2
- -- 1 is 100.00 at tax rate 1
3
- -- 2 is 50.00 at tax rate 2
4
- -- 3 is 864.20 at tax rate null
@@ -1,4 +0,0 @@
1
- -- For consistency with line_item.sql:
2
- -- 1 is at 15%
3
- -- 2 is at 0%
4
- -- 3 is not applicable (null)
@@ -1,14 +0,0 @@
1
- DROP TABLE IF EXISTS taxable_records;
2
-
3
- CREATE TABLE taxable_records (
4
- id int primary key auto_increment,
5
- currency_code varchar(3),
6
- amount decimal(20,4),
7
- gross_amount decimal(20,4),
8
- tax_factor decimal(10,9)
9
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
10
-
11
- INSERT INTO taxable_records(id, currency_code, amount, gross_amount, tax_factor) values
12
- (1, 'GBP', 123.45, 141.09, 0.142857143);
13
-
14
- ALTER SEQUENCE taxable_records_id_seq start 1000;
@@ -1,35 +0,0 @@
1
- DROP TABLE IF EXISTS time_dependent_records;
2
-
3
- CREATE TABLE time_dependent_records (
4
- id2 int primary key auto_increment,
5
- valid_from2 datetime not null,
6
- valid_until2 datetime,
7
- replaced_by_id2 int,
8
- value2 varchar(255) not null,
9
- is_default2 tinyint(1) not null
10
- ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
11
-
12
- -- 2008 -> 2009 -> 2010 -> 2011
13
- --
14
- -- 1 -> none
15
- -- 2 -> 3 -> 4
16
- -- 5 -> 3
17
- -- none -> 6* -> 7* -> none
18
- -- 8 -> 9*
19
- -- 10
20
- --
21
- -- * = default
22
-
23
- INSERT INTO time_dependent_records(id2, valid_from2, valid_until2, replaced_by_id2, value2, is_default2) values
24
- ( 1, '2008-01-01 00:00:00', '2009-01-01 00:00:00', NULL, 'One', 0), -- false
25
- ( 2, '2008-01-01 00:00:00', '2009-01-01 00:00:00', 3, 'Two', 0), -- false
26
- ( 3, '2009-01-01 00:00:00', '2010-01-01 00:00:00', 4, 'Three', 0), -- false
27
- ( 4, '2010-01-01 00:00:00', NULL, NULL, 'Four', 0), -- false
28
- ( 5, '2008-01-01 00:00:00', '2009-01-01 00:00:00', 3, 'Five', 0), -- false
29
- ( 6, '2009-01-01 00:00:00', '2010-01-01 00:00:00', 7, 'Six', 1), -- true
30
- ( 7, '2010-01-01 00:00:00', '2011-01-01 00:00:00', NULL, 'Seven', 1), -- true
31
- ( 8, '2008-01-01 00:00:00', '2011-01-01 00:00:00', 9, 'Eight', 0), -- false
32
- ( 9, '2011-01-01 00:00:00', NULL, NULL, 'Nine', 1), -- true
33
- (10, '2008-01-01 00:00:00', NULL, NULL, 'Ten', 0); -- false
34
-
35
- ALTER SEQUENCE time_dependent_records_id2_seq start 1000;
@@ -1,444 +0,0 @@
1
- # encoding: utf-8
2
-
3
- require File.join(File.dirname(__FILE__), 'test_helper.rb')
4
-
5
- ####### Helper stuff
6
-
7
- module LedgerItemMethods
8
- RENAMED_METHODS = {
9
- :id => :id2, :type => :type2, :sender_id => :sender_id2, :recipient_id => :recipient_id2,
10
- :sender_details => :sender_details2, :recipient_details => :recipient_details2,
11
- :identifier => :identifier2, :issue_date => :issue_date2, :currency => :currency2,
12
- :total_amount => :total_amount2, :tax_amount => :tax_amount2, :status => :status2,
13
- :description => :description2, :period_start => :period_start2,
14
- :period_end => :period_end2, :uuid => :uuid2, :due_date => :due_date2,
15
- :line_items => :line_items2
16
- }
17
-
18
- def user_id_to_details_hash(user_id)
19
- case user_id
20
- when 1, nil
21
- {:is_self => true, :name => 'Unlimited Limited', :contact_name => "Mr B. Badger",
22
- :address => "The Sett\n5 Badger Lane\n", :city => "Badgertown", :state => "",
23
- :postal_code => "Badger999", :country => "England", :country_code => "GB",
24
- :tax_number => "123456789"}
25
- when 2
26
- {:name => 'Lovely Customer Inc.', :contact_name => "Fred",
27
- :address => "The pasture", :city => "Mootown", :state => "Cow Kingdom",
28
- :postal_code => "MOOO", :country => "Scotland", :country_code => "GB",
29
- :tax_number => "987654321"}
30
- when 3
31
- {:name => 'I drink milk', :address => "Guzzle guzzle", :city => "Cheesetown",
32
- :postal_code => "12345", :country => "United States", :country_code => "US"}
33
- when 4
34
- {:name => 'The taxman', :address => "ALL YOUR EARNINGS\r\n\tARE BELONG TO US",
35
- :city => 'Cumbernauld', :state => 'North Lanarkshire', :postal_code => "",
36
- :country => 'United Kingdom'}
37
- end
38
- end
39
-
40
- def sender_details2
41
- user_id_to_details_hash(sender_id2)
42
- end
43
-
44
- def recipient_details2
45
- user_id_to_details_hash(recipient_id2)
46
- end
47
-
48
- def description2
49
- "#{type2} #{id2}"
50
- end
51
- end
52
-
53
-
54
- ####### Classes for use in the tests
55
-
56
- class MyLedgerItem < ActiveRecord::Base
57
- set_primary_key 'id2'
58
- set_inheritance_column 'type2'
59
- set_table_name 'ledger_item_records'
60
- include LedgerItemMethods
61
- acts_as_ledger_item RENAMED_METHODS
62
- has_many :line_items2, :class_name => 'SuperLineItem', :foreign_key => 'ledger_item_id2'
63
- end
64
-
65
- class MyInvoice < MyLedgerItem
66
- acts_as_ledger_item :subtype => :invoice
67
- end
68
-
69
- class InvoiceSubtype < MyInvoice
70
- end
71
-
72
- class MyCreditNote < MyLedgerItem
73
- acts_as_credit_note
74
- end
75
-
76
- class MyPayment < MyLedgerItem
77
- acts_as_payment
78
- end
79
-
80
- class CorporationTaxLiability < MyLedgerItem
81
- def self.debit_when_sent_by_self
82
- true
83
- end
84
- end
85
-
86
- class UUIDNotPresentLedgerItem < ActiveRecord::Base
87
- set_primary_key 'id2'
88
- set_inheritance_column 'type2'
89
- set_table_name 'ledger_item_records'
90
- include LedgerItemMethods
91
-
92
- def get_class_info
93
- ledger_item_class_info
94
- end
95
- end
96
-
97
- class OverwrittenMethodsNotPresentLedgerItem < ActiveRecord::Base
98
- set_primary_key 'id2'
99
- set_inheritance_column 'type2'
100
- set_table_name 'ledger_item_records'
101
- acts_as_invoice LedgerItemMethods::RENAMED_METHODS
102
- end
103
-
104
-
105
- ####### The actual tests
106
-
107
- class LedgerItemTest < Test::Unit::TestCase
108
-
109
- def test_total_amount_is_currency_value
110
- record = MyLedgerItem.find(5)
111
- assert_equal '$432.10', record.total_amount2_formatted
112
- end
113
-
114
- def test_tax_amount_is_currency_value
115
- record = MyInvoice.find(1)
116
- assert_equal '£15.00', record.tax_amount2_formatted
117
- end
118
-
119
- def test_total_amount_negative_debit
120
- record = MyLedgerItem.find(5)
121
- assert_equal '−$432.10', record.total_amount2_formatted(:debit => :negative, :self_id => record.recipient_id2)
122
- assert_equal '$432.10', record.total_amount2_formatted(:debit => :negative, :self_id => record.sender_id2)
123
- end
124
-
125
- def test_total_amount_negative_credit
126
- record = MyLedgerItem.find(5)
127
- assert_equal '−$432.10', record.total_amount2_formatted(:credit => :negative, :self_id => record.sender_id2)
128
- assert_equal '$432.10', record.total_amount2_formatted(:credit => :negative, :self_id => record.recipient_id2)
129
- end
130
-
131
- def test_net_amount
132
- assert_equal BigDecimal('300'), MyInvoice.find(1).net_amount
133
- end
134
-
135
- def test_net_amount_nil
136
- assert_nil MyInvoice.new.net_amount
137
- end
138
-
139
- def test_net_amount_formatted
140
- assert_equal '£300.00', MyInvoice.find(1).net_amount_formatted
141
- end
142
-
143
- def test_sent_by_nil_is_treated_as_self
144
- assert MyInvoice.find(1).sent_by?(nil)
145
- assert MyCreditNote.find(3).sent_by?(nil)
146
- end
147
-
148
- def test_received_by_nil_is_treated_as_self
149
- assert InvoiceSubtype.find(2).received_by?(nil)
150
- assert CorporationTaxLiability.find(6).received_by?(nil)
151
- end
152
-
153
- def test_invoice_from_self_is_debit
154
- record = MyInvoice.find(1)
155
- assert_kind_of MyInvoice, record
156
- assert record.debit?(1)
157
- assert record.debit?(nil)
158
- end
159
-
160
- def test_invoice_to_self_is_credit
161
- record = InvoiceSubtype.find(2)
162
- assert_kind_of MyInvoice, record
163
- assert !record.debit?(1)
164
- assert !record.debit?(nil)
165
- end
166
-
167
- def test_invoice_to_customer_is_seen_as_credit_by_customer
168
- assert !MyInvoice.find(1).debit?(2)
169
- end
170
-
171
- def test_invoice_from_supplier_is_seen_as_debit_by_supplier
172
- assert InvoiceSubtype.find(2).debit?(2)
173
- end
174
-
175
- def test_credit_note_from_self_is_debit
176
- record = MyCreditNote.find(3)
177
- assert_kind_of MyCreditNote, record
178
- assert record.debit?(nil)
179
- assert record.debit?(1)
180
- end
181
-
182
- def test_credit_note_to_customer_is_seen_as_credit_by_customer
183
- assert !MyCreditNote.find(3).debit?(2)
184
- end
185
-
186
- def test_payment_receipt_from_self_is_credit
187
- record = MyPayment.find(4)
188
- assert_kind_of MyPayment, record
189
- assert !record.debit?(1)
190
- assert !record.debit?(nil)
191
- end
192
-
193
- def test_payment_receipt_to_customer_is_seen_as_debit_by_customer
194
- assert MyPayment.find(4).debit?(2)
195
- end
196
-
197
- def test_cannot_determine_debit_status_for_uninvolved_party
198
- assert_raise ArgumentError do
199
- MyInvoice.find(1).debit?(3)
200
- end
201
- end
202
-
203
- def test_assign_uuid_to_new_record
204
- record = MyInvoice.new
205
- begin
206
- UUID
207
- uuid_gem_available = true
208
- rescue NameError
209
- uuid_gem_available = false
210
- end
211
- if uuid_gem_available
212
- assert_match /^[0-9a-f]{8}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{4}\-[0-9a-f]{12}$/, record.uuid2
213
- else
214
- assert record.uuid2.blank?
215
- puts "Warning: uuid gem not installed -- not testing UUID generation"
216
- end
217
- end
218
-
219
- def test_uuid_gem_not_present
220
- begin
221
- real_uuid = Object.send(:remove_const, :UUID) rescue nil
222
- UUIDNotPresentLedgerItem.acts_as_ledger_item(LedgerItemMethods::RENAMED_METHODS)
223
- assert_nil UUIDNotPresentLedgerItem.new.get_class_info.uuid_generator
224
- ensure
225
- Object.send(:const_set, :UUID, real_uuid) unless real_uuid.nil?
226
- end
227
- end
228
-
229
- def test_must_overwrite_sender_details
230
- assert_raise RuntimeError do
231
- OverwrittenMethodsNotPresentLedgerItem.new.sender_details
232
- end
233
- end
234
-
235
- def test_must_overwrite_recipient_details
236
- assert_raise RuntimeError do
237
- OverwrittenMethodsNotPresentLedgerItem.new.recipient_details
238
- end
239
- end
240
-
241
- def test_must_provide_line_items_association
242
- assert_raise RuntimeError do
243
- OverwrittenMethodsNotPresentLedgerItem.new.line_items
244
- end
245
- end
246
-
247
- def test_calculate_total_amount_for_new_invoice
248
- invoice = MyInvoice.new(:currency2 => 'USD')
249
- invoice.line_items2 << SuperLineItem.new(:net_amount2 => 100, :tax_amount2 => 15)
250
- invoice.line_items2 << SubLineItem.new(:net_amount2 => 10)
251
- invoice.valid?
252
- assert_equal BigDecimal('125'), invoice.total_amount2
253
- assert_equal BigDecimal('15'), invoice.tax_amount2
254
- end
255
-
256
- def test_calculate_total_amount_for_updated_invoice
257
- invoice = MyInvoice.find(9)
258
- invoice.line_items2 << SuperLineItem.new(:net_amount2 => 10, :tax_amount2 => 1.5)
259
- invoice.save!
260
- assert_equal([{'total_amount2' => '23.0000', 'tax_amount2' => '3.0000'}],
261
- ActiveRecord::Base.connection.select_all("SELECT total_amount2, tax_amount2 FROM ledger_item_records WHERE id2=9"))
262
- end
263
-
264
- def test_calculate_total_amount_for_updated_line_item
265
- # This might occur while an invoice is still open
266
- invoice = MyInvoice.find(9)
267
- invoice.line_items2[0].net_amount2 = '20'
268
- invoice.line_items2[0].tax_amount2 = 3
269
- invoice.save!
270
- assert_equal([{'total_amount2' => '23.0000', 'tax_amount2' => '3.0000'}],
271
- ActiveRecord::Base.connection.select_all("SELECT total_amount2, tax_amount2 FROM ledger_item_records WHERE id2=9"))
272
- assert_equal BigDecimal('23'), invoice.total_amount2
273
- assert_equal BigDecimal('3'), invoice.tax_amount2
274
- end
275
-
276
- def test_do_not_overwrite_total_amount_for_payment_without_line_items
277
- payment = MyPayment.new :total_amount2 => 23.45
278
- payment.save!
279
- assert_equal([{'total_amount2' => '23.4500'}],
280
- ActiveRecord::Base.connection.select_all("SELECT total_amount2 FROM ledger_item_records WHERE id2=#{payment.id}"))
281
- end
282
-
283
- def test_line_items_error
284
- assert_raise RuntimeError do
285
- MyInvoice.find(1).line_items # not line_items2
286
- end
287
- end
288
-
289
- def test_find_invoice_subclasses
290
- assert_equal %w(InvoiceSubtype MyInvoice), MyLedgerItem.select_matching_subclasses(:is_invoice, true).map{|c| c.name}.sort
291
- end
292
-
293
- def test_find_credit_note_subclasses
294
- assert_equal %w(MyCreditNote), MyLedgerItem.select_matching_subclasses(:is_credit_note, true).map{|c| c.name}
295
- end
296
-
297
- def test_find_payment_subclasses
298
- assert_equal %w(MyPayment), MyLedgerItem.select_matching_subclasses(:is_payment, true).map{|c| c.name}
299
- end
300
-
301
- def test_account_summary
302
- summary = MyLedgerItem.account_summary(1, 2)
303
- assert_equal [:GBP], summary.keys
304
- assert_equal BigDecimal('257.50'), summary[:GBP].sales
305
- assert_equal BigDecimal('141.97'), summary[:GBP].purchases
306
- assert_equal BigDecimal('256.50'), summary[:GBP].sale_receipts
307
- assert_equal BigDecimal('0.00'), summary[:GBP].purchase_payments
308
- assert_equal BigDecimal('-140.97'), summary[:GBP].balance
309
- end
310
-
311
- def test_account_summary_with_scope
312
- conditions = ['issue_date2 >= ? AND issue_date2 < ?', DateTime.parse('2008-01-01'), DateTime.parse('2009-01-01')]
313
- summary = MyLedgerItem.scoped(:conditions => conditions).account_summary(1, 2)
314
- assert_equal BigDecimal('257.50'), summary[:GBP].sales
315
- assert_equal BigDecimal('0.00'), summary[:GBP].purchases
316
- assert_equal BigDecimal('256.50'), summary[:GBP].sale_receipts
317
- assert_equal BigDecimal('0.00'), summary[:GBP].purchase_payments
318
- assert_equal BigDecimal('1.00'), summary[:GBP].balance
319
- end
320
-
321
- def test_account_summaries
322
- summaries = MyLedgerItem.account_summaries(2)
323
- assert_equal [1, 3], summaries.keys
324
- assert_equal [:GBP], summaries[1].keys
325
- assert_equal BigDecimal('257.50'), summaries[1][:GBP].purchases
326
- assert_equal BigDecimal('141.97'), summaries[1][:GBP].sales
327
- assert_equal BigDecimal('256.50'), summaries[1][:GBP].purchase_payments
328
- assert_equal BigDecimal('0.00'), summaries[1][:GBP].sale_receipts
329
- assert_equal BigDecimal('140.97'), summaries[1][:GBP].balance
330
- assert_equal [:USD], summaries[3].keys
331
- assert_equal BigDecimal('0.00'), summaries[3][:USD].purchases
332
- assert_equal BigDecimal('0.00'), summaries[3][:USD].sales
333
- assert_equal BigDecimal('0.00'), summaries[3][:USD].purchase_payments
334
- assert_equal BigDecimal('432.10'), summaries[3][:USD].sale_receipts
335
- assert_equal BigDecimal('-432.10'), summaries[3][:USD].balance
336
- end
337
-
338
- def test_account_summaries_with_scope
339
- conditions = {:conditions => ['issue_date2 < ?', DateTime.parse('2008-07-01')]}
340
- summaries = MyLedgerItem.scoped(conditions).account_summaries(2)
341
- assert_equal [1, 3], summaries.keys
342
- assert_equal [:GBP], summaries[1].keys
343
- assert_equal BigDecimal('315.00'), summaries[1][:GBP].purchases
344
- assert_equal BigDecimal('0.00'), summaries[1][:GBP].sales
345
- assert_equal BigDecimal('0.00'), summaries[1][:GBP].purchase_payments
346
- assert_equal BigDecimal('0.00'), summaries[1][:GBP].sale_receipts
347
- assert_equal BigDecimal('-315.00'), summaries[1][:GBP].balance
348
- assert_equal [:USD], summaries[3].keys
349
- assert_equal BigDecimal('0.00'), summaries[3][:USD].purchases
350
- assert_equal BigDecimal('0.00'), summaries[3][:USD].sales
351
- assert_equal BigDecimal('0.00'), summaries[3][:USD].purchase_payments
352
- assert_equal BigDecimal('432.10'), summaries[3][:USD].sale_receipts
353
- assert_equal BigDecimal('-432.10'), summaries[3][:USD].balance
354
- end
355
-
356
- def test_account_summary_over_all_others
357
- summary = MyLedgerItem.account_summary(1)
358
- assert_equal [:GBP], summary.keys
359
- assert_equal BigDecimal('257.50'), summary[:GBP].sales
360
- assert_equal BigDecimal('666808.63'), summary[:GBP].purchases
361
- assert_equal BigDecimal('256.50'), summary[:GBP].sale_receipts
362
- assert_equal BigDecimal('0.00'), summary[:GBP].purchase_payments
363
- assert_equal BigDecimal('-666807.63'), summary[:GBP].balance
364
- end
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
-
376
- def test_account_summary_to_s
377
- assert_equal "sales = £257.50; purchases = £666,808.63; sale_receipts = £256.50; " +
378
- "purchase_payments = £0.00; balance = −£666,807.63", MyLedgerItem.account_summary(1)[:GBP].to_s
379
- end
380
-
381
- def test_account_summary_formatting
382
- summary = MyLedgerItem.account_summary(1, 2)
383
- assert_equal [:GBP], summary.keys
384
- assert_equal '£257.50', summary[:GBP].sales_formatted
385
- assert_equal '£141.97', summary[:GBP].purchases_formatted
386
- assert_equal '£256.50', summary[:GBP].sale_receipts_formatted
387
- assert_equal '£0.00', summary[:GBP].purchase_payments_formatted
388
- assert_equal '−£140.97', summary[:GBP].balance_formatted
389
- end
390
-
391
- def test_account_summary_object_call_unknown_method
392
- assert_raise NoMethodError do
393
- MyLedgerItem.account_summary(1, 2)[:GBP].this_method_does_not_exist
394
- end
395
- end
396
-
397
- def test_sender_recipient_name_map_all
398
- assert_equal({1 => 'Unlimited Limited', 2 => 'Lovely Customer Inc.', 3 => 'I drink milk',
399
- 4 => 'The taxman'}, MyLedgerItem.sender_recipient_name_map([1,2,3,4]))
400
- end
401
-
402
- def test_sender_recipient_name_map_subset
403
- assert_equal({1 => 'Unlimited Limited', 3 => 'I drink milk'}, MyLedgerItem.sender_recipient_name_map([1,3]))
404
- end
405
-
406
- def test_sent_by_scope
407
- assert_equal [2,5], MyLedgerItem.sent_by(2).map{|i| i.id}.sort
408
- end
409
-
410
- def test_received_by_scope
411
- assert_equal [1,3,4,7,8,9,10,11], MyLedgerItem.received_by(2).map{|i| i.id}.sort
412
- end
413
-
414
- def test_sent_or_received_by_scope
415
- assert_equal [1,2,3,4,5,7,8,9,10,11], MyLedgerItem.sent_or_received_by(2).map{|i| i.id}.sort
416
- end
417
-
418
- def test_in_effect_scope
419
- assert_equal [1,2,3,4,5,6,7,8,9,10,11], MyLedgerItem.all.map{|i| i.id}.sort
420
- assert_equal [1,2,3,4,5,6,11], MyLedgerItem.in_effect.map{|i| i.id}.sort
421
- end
422
-
423
- def test_open_or_pending_scope
424
- assert_equal [8,9], MyLedgerItem.open_or_pending.map{|i| i.id}.sort
425
- end
426
-
427
- def test_due_at_scope
428
- assert_equal [1,3,4,7,8,10,11], MyLedgerItem.due_at(DateTime.parse('2009-01-30')).map{|i| i.id}.sort
429
- assert_equal [1,2,3,4,7,8,10,11], MyLedgerItem.due_at(DateTime.parse('2009-01-31')).map{|i| i.id}.sort
430
- end
431
-
432
- def test_sorted_scope
433
- assert_equal [5,1,4,3,8,2,6,7,9,10,11], MyLedgerItem.sorted(:issue_date).map{|i| i.id}
434
- end
435
-
436
- def test_sorted_scope_with_non_existent_column
437
- assert_equal [1,2,3,4,5,6,7,8,9,10,11], MyLedgerItem.sorted(:this_column_does_not_exist).map{|i| i.id}
438
- end
439
-
440
- def test_exclude_empty_invoices_scope
441
- assert_equal [1,2,3,4,5,6,7,8,9,10], MyLedgerItem.exclude_empty_invoices.map{|i| i.id}.sort
442
- end
443
-
444
- end