invoicing 0.2.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
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