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.
- checksums.yaml +7 -0
- data/LICENSE +1 -0
- data/README.md +57 -0
- data/Rakefile +16 -37
- data/lib/invoicing.rb +20 -10
- data/lib/invoicing/cached_record.rb +9 -6
- data/lib/invoicing/class_info.rb +34 -34
- data/lib/invoicing/connection_adapter_ext.rb +4 -4
- data/lib/invoicing/countries/uk.rb +6 -6
- data/lib/invoicing/currency_value.rb +39 -32
- data/lib/invoicing/find_subclasses.rb +40 -15
- data/lib/invoicing/ledger_item.rb +166 -145
- data/lib/invoicing/ledger_item/pdf_generator.rb +108 -0
- data/lib/invoicing/ledger_item/render_html.rb +76 -73
- data/lib/invoicing/ledger_item/render_ubl.rb +37 -35
- data/lib/invoicing/line_item.rb +43 -38
- data/lib/invoicing/price.rb +1 -1
- data/lib/invoicing/tax_rate.rb +3 -6
- data/lib/invoicing/taxable.rb +37 -32
- data/lib/invoicing/time_dependent.rb +40 -40
- data/lib/invoicing/version.rb +4 -4
- data/lib/rails/generators/invoicing/invoicing_generator.rb +14 -0
- data/lib/rails/generators/invoicing/ledger_item/ledger_item_generator.rb +17 -0
- data/lib/rails/generators/invoicing/ledger_item/templates/migration.rb +25 -0
- data/lib/rails/generators/invoicing/ledger_item/templates/model.rb +5 -0
- data/lib/rails/generators/invoicing/line_item/line_item_generator.rb +17 -0
- data/lib/rails/generators/invoicing/line_item/templates/migration.rb +20 -0
- data/lib/rails/generators/invoicing/line_item/templates/model.rb +5 -0
- data/lib/rails/generators/invoicing/tax_rate/tax_rate_generator.rb +17 -0
- data/lib/rails/generators/invoicing/tax_rate/templates/migration.rb +14 -0
- data/lib/rails/generators/invoicing/tax_rate/templates/model.rb +3 -0
- metadata +110 -153
- data.tar.gz.sig +0 -1
- data/History.txt +0 -31
- data/Manifest.txt +0 -62
- data/PostInstall.txt +0 -10
- data/README.rdoc +0 -58
- data/script/console +0 -10
- data/script/destroy +0 -14
- data/script/generate +0 -14
- data/tasks/rcov.rake +0 -4
- data/test/cached_record_test.rb +0 -100
- data/test/class_info_test.rb +0 -253
- data/test/connection_adapter_ext_test.rb +0 -79
- data/test/currency_value_test.rb +0 -209
- data/test/find_subclasses_test.rb +0 -120
- data/test/fixtures/README +0 -7
- data/test/fixtures/cached_record.sql +0 -22
- data/test/fixtures/class_info.sql +0 -28
- data/test/fixtures/currency_value.sql +0 -29
- data/test/fixtures/find_subclasses.sql +0 -43
- data/test/fixtures/ledger_item.sql +0 -39
- data/test/fixtures/line_item.sql +0 -33
- data/test/fixtures/price.sql +0 -4
- data/test/fixtures/tax_rate.sql +0 -4
- data/test/fixtures/taxable.sql +0 -14
- data/test/fixtures/time_dependent.sql +0 -35
- data/test/ledger_item_test.rb +0 -444
- data/test/line_item_test.rb +0 -139
- data/test/models/README +0 -4
- data/test/models/test_subclass_in_another_file.rb +0 -3
- data/test/models/test_subclass_not_in_database.rb +0 -6
- data/test/price_test.rb +0 -9
- data/test/ref-output/creditnote3.html +0 -82
- data/test/ref-output/creditnote3.xml +0 -89
- data/test/ref-output/invoice1.html +0 -93
- data/test/ref-output/invoice1.xml +0 -111
- data/test/ref-output/invoice2.html +0 -86
- data/test/ref-output/invoice2.xml +0 -98
- data/test/ref-output/invoice_null.html +0 -36
- data/test/render_html_test.rb +0 -70
- data/test/render_ubl_test.rb +0 -44
- data/test/setup.rb +0 -37
- data/test/tax_rate_test.rb +0 -9
- data/test/taxable_test.rb +0 -180
- data/test/test_helper.rb +0 -72
- data/test/time_dependent_test.rb +0 -180
- 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;
|
data/test/fixtures/line_item.sql
DELETED
@@ -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;
|
data/test/fixtures/price.sql
DELETED
data/test/fixtures/tax_rate.sql
DELETED
data/test/fixtures/taxable.sql
DELETED
@@ -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;
|
data/test/ledger_item_test.rb
DELETED
@@ -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
|