chiliproject_invoice 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (45) hide show
  1. data/COPYRIGHT.txt +18 -0
  2. data/CREDITS.rdoc +4 -0
  3. data/GPL.txt +339 -0
  4. data/README.rdoc +57 -0
  5. data/Rakefile +34 -0
  6. data/VERSION +1 -0
  7. data/app/controllers/invoice_controller.rb +94 -0
  8. data/app/controllers/payments_controller.rb +35 -0
  9. data/app/helpers/invoices_helper.rb +52 -0
  10. data/app/models/autofill.rb +69 -0
  11. data/app/models/invoice.rb +70 -0
  12. data/app/models/payment.rb +10 -0
  13. data/app/views/invoice/_form.rhtml +34 -0
  14. data/app/views/invoice/_row.rhtml +17 -0
  15. data/app/views/invoice/_table.rhtml +11 -0
  16. data/app/views/invoice/autocreate.rhtml +48 -0
  17. data/app/views/invoice/autofill.js.rjs +28 -0
  18. data/app/views/invoice/edit.rhtml +17 -0
  19. data/app/views/invoice/index.rhtml +26 -0
  20. data/app/views/invoice/new.rhtml +15 -0
  21. data/app/views/invoice/show.rhtml +63 -0
  22. data/app/views/layouts/print.rhtml +12 -0
  23. data/app/views/payments/_payment.html.erb +4 -0
  24. data/app/views/payments/new.html.erb +38 -0
  25. data/app/views/settings/_invoice_settings.rhtml +37 -0
  26. data/assets/images/creditcards.png +0 -0
  27. data/assets/images/money.png +0 -0
  28. data/assets/images/money_add.png +0 -0
  29. data/assets/images/printer.png +0 -0
  30. data/assets/stylesheets/invoice.css +36 -0
  31. data/assets/stylesheets/invoice_print.css +5 -0
  32. data/config/locales/en.yml +31 -0
  33. data/config/locales/fr.yml +14 -0
  34. data/config/routes.rb +15 -0
  35. data/init.rb +50 -0
  36. data/lang/en.yml +30 -0
  37. data/lang/fr.yml +13 -0
  38. data/lib/invoice_compatibility.rb +16 -0
  39. data/rails/init.rb +1 -0
  40. data/test/functional/invoice_controller_test.rb +25 -0
  41. data/test/integration/access_test.rb +86 -0
  42. data/test/integration/routing_test.rb +31 -0
  43. data/test/test_helper.rb +24 -0
  44. data/test/unit/invoice_test.rb +82 -0
  45. metadata +114 -0
data/lang/fr.yml ADDED
@@ -0,0 +1,13 @@
1
+ field_invoice_number: Numéro de facture
2
+ field_customer: Client
3
+ field_invoiced_on: Date de facturation
4
+ field_amount: Montant facturé
5
+ field_date_from: De
6
+ field_date_to: Vers
7
+ field_rate: Tarif heure
8
+ field_invoice: Facture
9
+ field_applied_on: Paiement appliqué sur
10
+ field_note: Note du paiement
11
+ label_open_invoices: Factures ouvertes
12
+ label_late_invoices: Factures en retard
13
+ label_closed_invoices: Factures fermées
@@ -0,0 +1,16 @@
1
+ # Wrappers around the Redmine core API changes between versions
2
+ module InvoiceCompatibility
3
+ class Enumeration
4
+ # Wrapper around Redmine's API since Enumerations changed in r2472
5
+ # This can be removed once 0.9.0 is stable
6
+ def self.activities
7
+ if Object.const_defined?('TimeEntryActivity')
8
+ return ::TimeEntryActivity.all
9
+ elsif ::Enumeration.respond_to?(:activities)
10
+ return ::Enumeration.activities
11
+ else
12
+ return ::Enumeration::get_values('ACTI')
13
+ end
14
+ end
15
+ end
16
+ end
data/rails/init.rb ADDED
@@ -0,0 +1 @@
1
+ require File.dirname(__FILE__) + "/../init"
@@ -0,0 +1,25 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class InvoiceControllerTest < ActionController::TestCase
4
+ context "on GET to autofill.js" do
5
+ setup do
6
+ @user = User.generate_with_protected!(:admin => true)
7
+ @request.session[:user_id] = @user.id
8
+
9
+ @customer = Customer.create!(:name => 'customer')
10
+ @project = Project.generate!(:customer_id => @customer.id)
11
+
12
+ get :autofill, :format => 'js', :autofill => {
13
+ :project_id => @project.id,
14
+ :date_from => '2010-01-01',
15
+ :date_to => '2010-02-01'
16
+ }
17
+ end
18
+
19
+ should_assign_to :autofill
20
+
21
+ should_respond_with :success
22
+ should_render_template :autofill
23
+ should_not_set_the_flash
24
+ end
25
+ end
@@ -0,0 +1,86 @@
1
+ require "#{File.dirname(__FILE__)}/../test_helper"
2
+
3
+ class AccessTest < ActionController::IntegrationTest
4
+ def setup
5
+ super
6
+ @user = User.generate_with_protected!(:login => 'user', :password => 'password', :password_confirmation => 'password')
7
+ log_user('user', 'password')
8
+
9
+ @project = Project.generate!
10
+ @role = Role.generate!(:permissions => [:view_issues])
11
+ @member = Member.generate!(:principal => @user, :project => @project, :roles => [@role])
12
+ @customer = Customer.create!(:name => 'customer')
13
+ @invoice = Invoice.generate!(:customer => @customer)
14
+ end
15
+
16
+ def add_permission_to_role(permission)
17
+ @role.permissions << permission
18
+ @role.save!
19
+ end
20
+
21
+ context "as a user without :show_invoices permission" do
22
+ should_be_denied_access_to("/invoices/index") { get "/invoice" }
23
+ should_be_denied_access_to("/invoices/show") { get "/invoice/show" }
24
+ end
25
+
26
+ context "as a user with :show_invoices permission" do
27
+ setup do
28
+ add_permission_to_role(:show_invoices)
29
+ end
30
+
31
+ should_be_allowed_access_to("/invoices/index") { get "/invoice" }
32
+ should_be_allowed_access_to("/invoices/show") { get "/invoice/#{@invoice.id}" }
33
+ end
34
+
35
+ context "as a user without :edit_invoices permission" do
36
+ should_be_denied_access_to("/invoices/new") { get "/invoice/new" }
37
+ should_be_denied_access_to("/invoices/edit") { get "/invoice/#{@invoice.id}/edit" }
38
+ should_be_denied_access_to("/invoices/autocreate") { get "/invoice/autocreate" }
39
+ should_be_denied_access_to("/invoices/autofill") { get "/invoice/autofill" }
40
+ should_be_denied_access_to("/invoices/create") { post "/invoice/create" }
41
+ should_be_denied_access_to("/invoices/update") { put "/invoice/#{@invoice.id}" }
42
+ end
43
+
44
+ context "as a user with :edit_invoices permission" do
45
+ setup do
46
+ add_permission_to_role(:show_invoices)
47
+ add_permission_to_role(:edit_invoices)
48
+ end
49
+
50
+ should_be_allowed_access_to("/invoices/new") { get "/invoice/new" }
51
+ should_be_allowed_access_to("/invoices/edit") { get "/invoice/#{@invoice.id}/edit" }
52
+ should_be_allowed_access_to("/invoices/autocreate") { get "/invoice/autocreate" }
53
+ should_be_allowed_access_to("/invoices/autofill") { get "/invoice/autofill" }
54
+ should_be_allowed_access_to("/invoices/create") { post "/invoice/create" }
55
+ should_be_allowed_access_to("/invoices/update") { put_via_redirect "/invoice/#{@invoice.id}" }
56
+ end
57
+
58
+ context "as a user without :delete_invoices permission" do
59
+ should_be_denied_access_to("/invoices/destroy") { delete "/invoice/#{@invoice.id}" }
60
+ end
61
+
62
+ context "as a user with :delete_invoices permission" do
63
+ setup do
64
+ add_permission_to_role(:show_invoices)
65
+ add_permission_to_role(:delete_invoices)
66
+ end
67
+
68
+ should_be_allowed_access_to("/invoices/destroy") { delete_via_redirect "/invoice/#{@invoice.id}" }
69
+ end
70
+
71
+ context "as a user without :pay_invoices permission" do
72
+ should_be_denied_access_to("/payments/new") { get "/payments/new" }
73
+ should_be_denied_access_to("/payments/create") { post "/payments/create" }
74
+ should_be_denied_access_to("/invoices/outstanding") { get "/invoice/#{@invoice.id}/outstanding" }
75
+ end
76
+
77
+ context "as a user with :pay_invoices permission" do
78
+ setup do
79
+ add_permission_to_role(:pay_invoices)
80
+ end
81
+
82
+ should_be_allowed_access_to("/payments/new") { get "/payments/new" }
83
+ should_be_allowed_access_to("/payments/create") { post "/payments/create" }
84
+ should_be_allowed_access_to("/invoices/outstanding") { get "/invoice/#{@invoice.id}/outstanding" }
85
+ end
86
+ end
@@ -0,0 +1,31 @@
1
+ require "#{File.dirname(__FILE__)}/../test_helper"
2
+
3
+ class RoutingTest < ActionController::IntegrationTest
4
+ context "invoices" do
5
+ should_route :get, "/invoice", :controller => 'invoice', :action => 'index'
6
+ should_route :get, "/invoice/new", :controller => 'invoice', :action => 'new'
7
+ should_route :get, "/invoice/autocreate", :controller => 'invoice', :action => 'autocreate'
8
+ should_route :get, "/invoice/100", :controller => 'invoice', :action => 'show', :id => '100'
9
+ should_route :get, "/invoice/100/edit", :controller => 'invoice', :action => 'edit', :id => '100'
10
+ should_route :get, "/invoice/autofill", :controller => 'invoice', :action => 'autofill'
11
+ should_route :get, "/invoice/100/outstanding", :controller => 'invoice', :action => 'outstanding', :id => '100'
12
+
13
+
14
+ should_route :post, "/invoice", :controller => 'invoice', :action => 'create'
15
+
16
+ should_route :put, "/invoice/100", :controller => 'invoice', :action => 'update', :id => '100'
17
+
18
+ should_route :delete, "/invoice/100", :controller => 'invoice', :action => 'destroy', :id => '100'
19
+ end
20
+
21
+ context "payments" do
22
+ should_route :get, "/payments/new", :controller => 'payments', :action => 'new'
23
+
24
+ should_route :post, "/payments", :controller => 'payments', :action => 'create'
25
+
26
+ should_route :get, "/invoice/100/payments/new", :controller => 'payments', :action => 'new', :invoice_id => '100'
27
+
28
+ should_route :post, "/invoice/100/payments", :controller => 'payments', :action => 'create', :invoice_id => '100'
29
+ end
30
+
31
+ end
@@ -0,0 +1,24 @@
1
+ # Load the normal Rails helper
2
+ require File.expand_path(File.dirname(__FILE__) + '/../../../../test/test_helper')
3
+
4
+ # Ensure that we are using the temporary fixture path
5
+ Engines::Testing.set_fixture_path
6
+
7
+ class Test::Unit::TestCase
8
+ def self.should_be_denied_access_to(route_name, &block)
9
+ should "be deined access to #{route_name}" do
10
+ instance_eval &block
11
+ assert_response :forbidden
12
+ assert_template 'common/error'
13
+ end
14
+ end
15
+
16
+ def self.should_be_allowed_access_to(route_name, &block)
17
+ should "be allowed access to #{route_name}" do
18
+ instance_eval &block
19
+
20
+ assert_response :success
21
+ end
22
+ end
23
+
24
+ end
@@ -0,0 +1,82 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ class InvoiceTest < ActiveSupport::TestCase
4
+ should_belong_to :customer
5
+ should_belong_to :project
6
+ should_have_many :payments
7
+
8
+ should_validate_presence_of :invoice_number
9
+ should_validate_presence_of :customer
10
+ should_validate_presence_of :amount
11
+ should_validate_presence_of :description
12
+
13
+ context "#open" do
14
+ should "only return open invoices" do
15
+ customer = Customer.create!(:name => 'customer')
16
+ open1 = Invoice.generate!(:customer => customer)
17
+ open2 = Invoice.generate!(:customer => customer)
18
+ paid = Invoice.generate!(:amount => 100.0, :customer => customer)
19
+ Payment.generate!(:amount => 100.0, :invoice => paid)
20
+
21
+ open_invoices = Invoice.open
22
+ assert open_invoices.all? {|invoice| invoice.open? }
23
+ assert_contains open_invoices, open1
24
+ assert_contains open_invoices, open2
25
+ end
26
+ end
27
+
28
+ context "#outstanding" do
29
+ setup do
30
+ customer = Customer.create!(:name => 'customer')
31
+ @invoice = Invoice.generate!(:amount => 100.0, :customer => customer)
32
+ end
33
+
34
+ should "return the total unpaid amount left on an invoice" do
35
+ Payment.generate!(:amount => 10, :invoice => @invoice)
36
+
37
+ assert_equal @invoice.amount - 10, @invoice.outstanding
38
+ end
39
+
40
+ should "return 0.0 if the invoice is fully paid" do
41
+ Payment.generate!(:amount => @invoice.amount, :invoice => @invoice)
42
+
43
+ assert_equal 0.0, @invoice.outstanding
44
+ end
45
+
46
+ should "return 0.0 if the invoice is over paid" do
47
+ Payment.generate!(:amount => @invoice.amount + 25.0, :invoice => @invoice)
48
+
49
+ assert_equal 0.0, @invoice.outstanding
50
+ end
51
+
52
+ should "return the base amount if there are no payments" do
53
+ assert_equal @invoice.amount, @invoice.outstanding
54
+ end
55
+ end
56
+
57
+ context "#fully_paid?" do
58
+ setup do
59
+ customer = Customer.create!(:name => 'customer')
60
+ @invoice = Invoice.generate!(:amount => 100.0, :customer => customer)
61
+ end
62
+
63
+ should "return false if the outstanding amount is greater than 0" do
64
+ Payment.generate!(:amount => 10, :invoice => @invoice)
65
+
66
+ assert !@invoice.fully_paid?
67
+ end
68
+
69
+ should "return true if the outstanding amount is less than 0" do
70
+ Payment.generate!(:amount => @invoice.amount + 10, :invoice => @invoice)
71
+
72
+ assert @invoice.fully_paid?
73
+ end
74
+
75
+ should "return true if the outstanding amount is equal to 0" do
76
+ Payment.generate!(:amount => @invoice.amount, :invoice => @invoice)
77
+
78
+ assert @invoice.fully_paid?
79
+ end
80
+
81
+ end
82
+ end
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: chiliproject_invoice
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Eric Davis
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-04-28 00:00:00 -07:00
19
+ default_executable:
20
+ dependencies: []
21
+
22
+ description: ChiliProject plugin to create and manage invoices
23
+ email: edavis@littlestreamsoftware.com
24
+ executables: []
25
+
26
+ extensions: []
27
+
28
+ extra_rdoc_files:
29
+ - README.rdoc
30
+ files:
31
+ - COPYRIGHT.txt
32
+ - CREDITS.rdoc
33
+ - GPL.txt
34
+ - README.rdoc
35
+ - Rakefile
36
+ - VERSION
37
+ - app/controllers/invoice_controller.rb
38
+ - app/controllers/payments_controller.rb
39
+ - app/helpers/invoices_helper.rb
40
+ - app/models/autofill.rb
41
+ - app/models/invoice.rb
42
+ - app/models/payment.rb
43
+ - app/views/invoice/_form.rhtml
44
+ - app/views/invoice/_row.rhtml
45
+ - app/views/invoice/_table.rhtml
46
+ - app/views/invoice/autocreate.rhtml
47
+ - app/views/invoice/autofill.js.rjs
48
+ - app/views/invoice/edit.rhtml
49
+ - app/views/invoice/index.rhtml
50
+ - app/views/invoice/new.rhtml
51
+ - app/views/invoice/show.rhtml
52
+ - app/views/layouts/print.rhtml
53
+ - app/views/payments/_payment.html.erb
54
+ - app/views/payments/new.html.erb
55
+ - app/views/settings/_invoice_settings.rhtml
56
+ - assets/images/creditcards.png
57
+ - assets/images/money.png
58
+ - assets/images/money_add.png
59
+ - assets/images/printer.png
60
+ - assets/stylesheets/invoice.css
61
+ - assets/stylesheets/invoice_print.css
62
+ - config/locales/en.yml
63
+ - config/locales/fr.yml
64
+ - config/routes.rb
65
+ - init.rb
66
+ - lang/en.yml
67
+ - lang/fr.yml
68
+ - lib/invoice_compatibility.rb
69
+ - rails/init.rb
70
+ - test/functional/invoice_controller_test.rb
71
+ - test/integration/access_test.rb
72
+ - test/integration/routing_test.rb
73
+ - test/test_helper.rb
74
+ - test/unit/invoice_test.rb
75
+ has_rdoc: true
76
+ homepage: https://projects.littlestreamsoftware.com/projects/chiliproject_invoice
77
+ licenses: []
78
+
79
+ post_install_message:
80
+ rdoc_options:
81
+ - --charset=UTF-8
82
+ require_paths:
83
+ - lib
84
+ required_ruby_version: !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ hash: 3
90
+ segments:
91
+ - 0
92
+ version: "0"
93
+ required_rubygems_version: !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ hash: 3
99
+ segments:
100
+ - 0
101
+ version: "0"
102
+ requirements: []
103
+
104
+ rubyforge_project:
105
+ rubygems_version: 1.3.7
106
+ signing_key:
107
+ specification_version: 3
108
+ summary: ChiliProject plugin to create and manage invoices
109
+ test_files:
110
+ - test/test_helper.rb
111
+ - test/integration/routing_test.rb
112
+ - test/integration/access_test.rb
113
+ - test/unit/invoice_test.rb
114
+ - test/functional/invoice_controller_test.rb