chiliproject_invoice 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYRIGHT.txt +18 -0
- data/CREDITS.rdoc +4 -0
- data/GPL.txt +339 -0
- data/README.rdoc +57 -0
- data/Rakefile +34 -0
- data/VERSION +1 -0
- data/app/controllers/invoice_controller.rb +94 -0
- data/app/controllers/payments_controller.rb +35 -0
- data/app/helpers/invoices_helper.rb +52 -0
- data/app/models/autofill.rb +69 -0
- data/app/models/invoice.rb +70 -0
- data/app/models/payment.rb +10 -0
- data/app/views/invoice/_form.rhtml +34 -0
- data/app/views/invoice/_row.rhtml +17 -0
- data/app/views/invoice/_table.rhtml +11 -0
- data/app/views/invoice/autocreate.rhtml +48 -0
- data/app/views/invoice/autofill.js.rjs +28 -0
- data/app/views/invoice/edit.rhtml +17 -0
- data/app/views/invoice/index.rhtml +26 -0
- data/app/views/invoice/new.rhtml +15 -0
- data/app/views/invoice/show.rhtml +63 -0
- data/app/views/layouts/print.rhtml +12 -0
- data/app/views/payments/_payment.html.erb +4 -0
- data/app/views/payments/new.html.erb +38 -0
- data/app/views/settings/_invoice_settings.rhtml +37 -0
- data/assets/images/creditcards.png +0 -0
- data/assets/images/money.png +0 -0
- data/assets/images/money_add.png +0 -0
- data/assets/images/printer.png +0 -0
- data/assets/stylesheets/invoice.css +36 -0
- data/assets/stylesheets/invoice_print.css +5 -0
- data/config/locales/en.yml +31 -0
- data/config/locales/fr.yml +14 -0
- data/config/routes.rb +15 -0
- data/init.rb +50 -0
- data/lang/en.yml +30 -0
- data/lang/fr.yml +13 -0
- data/lib/invoice_compatibility.rb +16 -0
- data/rails/init.rb +1 -0
- data/test/functional/invoice_controller_test.rb +25 -0
- data/test/integration/access_test.rb +86 -0
- data/test/integration/routing_test.rb +31 -0
- data/test/test_helper.rb +24 -0
- data/test/unit/invoice_test.rb +82 -0
- 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
|
data/test/test_helper.rb
ADDED
@@ -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
|