chiliproject_invoice 0.1.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.
- 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
|