billing 0.0.0 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/billing/accounts.js +2 -0
- data/app/assets/javascripts/billing/charges.js +2 -0
- data/app/assets/javascripts/billing/modifiers.js +2 -0
- data/app/assets/javascripts/billing/payments.js +2 -0
- data/app/assets/stylesheets/billing/accounts.css +4 -0
- data/app/assets/stylesheets/billing/charges.css +4 -0
- data/app/assets/stylesheets/billing/modifiers.css +4 -0
- data/app/assets/stylesheets/billing/payments.css +4 -0
- data/app/controllers/billing/accounts_controller.rb +29 -0
- data/app/controllers/billing/application_controller.rb +18 -0
- data/app/controllers/billing/charges_controller.rb +29 -0
- data/app/controllers/billing/modifiers_controller.rb +29 -0
- data/app/controllers/billing/payments_controller.rb +29 -0
- data/app/helpers/billing/accounts_helper.rb +4 -0
- data/app/helpers/billing/charges_helper.rb +4 -0
- data/app/helpers/billing/modifiers_helper.rb +4 -0
- data/app/helpers/billing/payments_helper.rb +4 -0
- data/app/models/billing/account.rb +66 -0
- data/app/models/billing/account_item.rb +15 -0
- data/app/models/billing/charge.rb +21 -0
- data/app/models/billing/modifier.rb +32 -0
- data/app/models/billing/modifier_items.rb +11 -0
- data/app/models/billing/origin.rb +4 -0
- data/app/models/billing/payment.rb +39 -0
- data/app/models/billing/payment_type.rb +6 -0
- data/app/models/billing/payment_with_type.rb +14 -0
- data/app/models/billing/plu.rb +4 -0
- data/app/models/billing/profile.rb +4 -0
- data/app/models/billing/tax_group.rb +4 -0
- data/app/views/billing/accounts/index.html.erb +7 -0
- data/app/views/billing/accounts/new.html.erb +8 -0
- data/app/views/billing/accounts/show.html.erb +29 -0
- data/app/views/billing/application/index.html.erb +3 -0
- data/app/views/billing/charges/new.html.erb +12 -0
- data/app/views/billing/modifiers/new.html.erb +18 -0
- data/app/views/billing/payments/new.html.erb +11 -0
- data/config/routes.rb +6 -0
- data/db/migrate/20140717180443_create_billing_accounts.rb +9 -0
- data/db/migrate/20140717181134_create_billing_charges.rb +11 -0
- data/db/migrate/20140717181406_create_billing_discounts.rb +11 -0
- data/db/migrate/20140717183129_create_billing_payments.rb +10 -0
- data/db/migrate/20140717202527_create_billing_origins.rb +9 -0
- data/db/migrate/20140718164841_add_sumaries_to_billing_account.rb +11 -0
- data/db/migrate/20140718210349_add_fixed_value_to_billing_discount.rb +7 -0
- data/db/migrate/20140718212116_create_billing_payment_types.rb +11 -0
- data/db/migrate/20140719094023_create_billing_tax_groups.rb +9 -0
- data/db/migrate/20140719094033_create_billing_plus.rb +9 -0
- data/db/migrate/20140719094418_create_billing_profiles.rb +9 -0
- data/db/migrate/20140719103621_rename_billing_discounts_to_modifiers.rb +5 -0
- data/db/migrate/20140719110412_add_surcharges_sum_to_billing_account.rb +7 -0
- data/db/migrate/20140720110811_add_type_to_billing_payment.rb +6 -0
- data/db/migrate/20140720132559_add_type_to_billing_payment_type.rb +5 -0
- data/lib/billing.rb +16 -0
- data/lib/billing/billable.rb +34 -0
- data/lib/billing/engine.rb +1 -0
- data/lib/billing/mapping.rb +32 -0
- data/lib/billing/routes.rb +16 -0
- data/lib/billing/version.rb +1 -1
- data/lib/tasks/billing.rake +7 -0
- data/test/controllers/billing/accounts_controller_test.rb +19 -0
- data/test/controllers/billing/charges_controller_test.rb +16 -0
- data/test/controllers/billing/modifiers_controller_test.rb +16 -0
- data/test/controllers/billing/payments_controller_test.rb +16 -0
- data/test/dummy/app/models/profile.rb +3 -0
- data/test/dummy/config/routes.rb +3 -2
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/migrate/20140718104656_create_profiles.rb +8 -0
- data/test/dummy/db/schema.rb +112 -0
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/development.log +1602 -0
- data/test/dummy/log/test.log +52069 -0
- data/test/dummy/test/fixtures/profiles.yml +11 -0
- data/test/dummy/test/models/profile_test.rb +7 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/02adf8ace512aefc4ef19b35aebc07f7 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/0cab887466527f5353fd43adab72769b +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/25b7c6efcbd128f109577104af58d084 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/2f52090f9e08ac02cd453b04af0df887 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/35a523ac3c33d6409a69faead4b2a882 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/3f4fc67be1dd91962f5a0026848dca77 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/43b3cc0ac6f63c0e1a3ab61fec84519d +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/59435066fc40e1ef5b45b0fd2c0eacf9 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/69cb965e6031d8099c185256f6fa8f90 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/6d34e4addaf3495d1d96306d164feb97 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/79316f9f3f5ebcec9b368d92d2e97e23 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/7ffc7e805e3fc08bae6a93e027a3e911 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/82ae0f4fbceb673c729b9bcb54a1161c +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/9509747efe602f6a81d50d9744f385f2 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/971b6b8d6c7a57e72d235e55537a2c44 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/b68d1e1a967e74abe3e10f643756ae67 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/cab3eca4515d1263ea8db2ff58df151d +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/cac68bb014ecc482b8f85312e49baa6f +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/d3ab844c61f1c211ed5fad5407cd18ef +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/d6d844128e4910cf773d1c48dd147e3b +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/e62907e54633a2adb53c33c1f59b79bf +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/e96b4e8fe0ebcceb51d202c8af7826ea +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/eb95e26896c1c6788657c4ef68a7e9e1 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/efaa0abeb4ad44b0ef8df996631f3997 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/f393277b28dd79320611f18a379dbea7 +0 -0
- data/test/dummy/tmp/cache/assets/test/sprockets/fbf1489a0c3d66a329f070c10cd77a03 +0 -0
- data/test/fixtures/billing/accounts.yml +11 -0
- data/test/fixtures/billing/charges.yml +15 -0
- data/test/fixtures/billing/modifiers.yml +14 -0
- data/test/fixtures/billing/origins.yml +7 -0
- data/test/fixtures/billing/payment_types.yml +11 -0
- data/test/fixtures/billing/payments.yml +15 -0
- data/test/fixtures/billing/plus.yml +7 -0
- data/test/fixtures/billing/profiles.yml +7 -0
- data/test/fixtures/billing/tax_groups.yml +7 -0
- data/test/fixtures/profiles.yml +1 -0
- data/test/helpers/billing/accounts_helper_test.rb +6 -0
- data/test/helpers/billing/charges_helper_test.rb +6 -0
- data/test/helpers/billing/modifiers_helper_test.rb +6 -0
- data/test/helpers/billing/payments_helper_test.rb +6 -0
- data/test/models/billing/account_test.rb +43 -0
- data/test/models/billing/charge_test.rb +17 -0
- data/test/models/billing/modifier_test.rb +19 -0
- data/test/models/billing/origin_test.rb +9 -0
- data/test/models/billing/payment_test.rb +17 -0
- data/test/models/billing/payment_type_test.rb +9 -0
- data/test/models/billing/plu_test.rb +9 -0
- data/test/models/billing/profile_test.rb +9 -0
- data/test/models/billing/tax_group_test.rb +9 -0
- data/test/test_helper.rb +28 -2
- metadata +199 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 747d5529859b70e9cc69f11653785d07d55b74a4
|
4
|
+
data.tar.gz: cfc4af81e2d5e2361a2bea947e7e2bb3cdc251f2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c6c723a641929e19b86cd4bbfd1e175606036f055ba0112691c82c5e573b08bbc411133c6c577aef41655859e85a100a26b5ed60ed3c6e7bd8a6f3c6d9b7f535
|
7
|
+
data.tar.gz: c6d5372d0418f727050175f5eddf78c67f2cf903545722a593e4c9a6bb2bab8342c769cfd9a4d21a3741ed40053dfa4d3d341483ad157606e83c3381b72bebdf
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require_dependency "billing/application_controller"
|
2
|
+
|
3
|
+
module Billing
|
4
|
+
class AccountsController < ApplicationController
|
5
|
+
before_action :set_account, except: [:index, :new, :create]
|
6
|
+
|
7
|
+
def index
|
8
|
+
@accounts = billable.billing_accounts
|
9
|
+
end
|
10
|
+
|
11
|
+
def new
|
12
|
+
@account = billable.billing_accounts.new
|
13
|
+
end
|
14
|
+
|
15
|
+
def create
|
16
|
+
@account = billable.billing_accounts.new
|
17
|
+
if @account.save
|
18
|
+
redirect_to @account
|
19
|
+
else
|
20
|
+
render action: :new
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
def set_account
|
26
|
+
@account = billable.billing_accounts.find(params[:id])
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -1,4 +1,22 @@
|
|
1
1
|
module Billing
|
2
2
|
class ApplicationController < ActionController::Base
|
3
|
+
prepend_before_filter :include_extra_module
|
4
|
+
helper_method :billable
|
5
|
+
|
6
|
+
def index
|
7
|
+
end
|
8
|
+
|
9
|
+
def billable
|
10
|
+
@billable ||= billing_mapping.i_klass.find_by(billing_mapping.i_find_key => params[billing_mapping.i_param])
|
11
|
+
end
|
12
|
+
|
13
|
+
private
|
14
|
+
def billing_mapping
|
15
|
+
@billing_mapping ||= Billing::Mapping.find(request.fullpath)
|
16
|
+
end
|
17
|
+
|
18
|
+
def include_extra_module
|
19
|
+
self.class.send(:include, billing_mapping.i_extra_module) if billing_mapping.i_extra_module.present?
|
20
|
+
end
|
3
21
|
end
|
4
22
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require_dependency "billing/application_controller"
|
2
|
+
|
3
|
+
module Billing
|
4
|
+
class ChargesController < ApplicationController
|
5
|
+
before_action :set_account
|
6
|
+
|
7
|
+
def new
|
8
|
+
@charge = @account.charges.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def create
|
12
|
+
@charge = @account.charges.new(charge_params)
|
13
|
+
if @charge.save
|
14
|
+
redirect_to @account
|
15
|
+
else
|
16
|
+
render action: :new
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
def set_account
|
22
|
+
@account = billable.billing_accounts.find(params[:account_id])
|
23
|
+
end
|
24
|
+
|
25
|
+
def charge_params
|
26
|
+
params.require(:charge).permit(:price)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require_dependency "billing/application_controller"
|
2
|
+
|
3
|
+
module Billing
|
4
|
+
class ModifiersController < ApplicationController
|
5
|
+
before_action :set_account
|
6
|
+
|
7
|
+
def new
|
8
|
+
@modifier = @account.modifiers.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def create
|
12
|
+
@modifier = @account.modifiers.new(modifier_params)
|
13
|
+
if @modifier.save
|
14
|
+
redirect_to @account
|
15
|
+
else
|
16
|
+
render action: :new
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
def set_account
|
22
|
+
@account = billable.billing_accounts.find(params[:account_id])
|
23
|
+
end
|
24
|
+
|
25
|
+
def modifier_params
|
26
|
+
params.require(:modifier).permit(:percent_ratio, :fixed_value, :charge_id)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require_dependency "billing/application_controller"
|
2
|
+
|
3
|
+
module Billing
|
4
|
+
class PaymentsController < ApplicationController
|
5
|
+
before_action :set_account
|
6
|
+
|
7
|
+
def new
|
8
|
+
@payment = @account.payments.new(value: @account.total)
|
9
|
+
end
|
10
|
+
|
11
|
+
def create
|
12
|
+
@payment = @account.payments.new(payment_params)
|
13
|
+
if @payment.save
|
14
|
+
redirect_to @account
|
15
|
+
else
|
16
|
+
render action: :new
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
def set_account
|
22
|
+
@account = billable.billing_accounts.find(params[:account_id])
|
23
|
+
end
|
24
|
+
|
25
|
+
def payment_params
|
26
|
+
params.require(:payment).permit(:value)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
module Billing
|
2
|
+
class Account < ActiveRecord::Base
|
3
|
+
monetize :charges_sum_cents
|
4
|
+
monetize :discounts_sum_cents
|
5
|
+
monetize :surcharges_sum_cents
|
6
|
+
monetize :payments_sum_cents
|
7
|
+
monetize :total_cents
|
8
|
+
monetize :balance_cents
|
9
|
+
|
10
|
+
belongs_to :billable, polymorphic: true
|
11
|
+
has_many :charges, inverse_of: :account
|
12
|
+
has_many :modifiers, inverse_of: :account
|
13
|
+
has_many :payments, inverse_of: :account
|
14
|
+
|
15
|
+
accepts_nested_attributes_for :charges, :modifiers, :payments
|
16
|
+
|
17
|
+
before_validation :update_sumaries
|
18
|
+
|
19
|
+
validates_numericality_of :total, greater_than_or_equal_to: 0
|
20
|
+
|
21
|
+
def charge(*args)
|
22
|
+
c = charges.new Charge.args(*args)
|
23
|
+
c if c.save
|
24
|
+
end
|
25
|
+
|
26
|
+
def modify(*args)
|
27
|
+
m = modifiers.new Modifier.args(*args)
|
28
|
+
m if m.save
|
29
|
+
end
|
30
|
+
|
31
|
+
def pay(*args)
|
32
|
+
p = payments.new Payment.args(*args)
|
33
|
+
p if p.save
|
34
|
+
end
|
35
|
+
|
36
|
+
def modifier_items
|
37
|
+
calculate_modifiers
|
38
|
+
end
|
39
|
+
|
40
|
+
def payment_types
|
41
|
+
billable.try(:billing_payment_types) || billable.try(:payment_types) || []
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
def calculate_modifiers
|
46
|
+
@modifier_items = ModifierItems.new.tap() do |items|
|
47
|
+
modifiers.each do |modifier|
|
48
|
+
if charge = modifier.charge
|
49
|
+
items << Charge.new(price: modifier.percent_ratio.nil? ? modifier.fixed_value : (charge.price * modifier.percent_ratio), chargable: charge)
|
50
|
+
else
|
51
|
+
items << Charge.new(price: modifier.percent_ratio.nil? ? modifier.fixed_value : (charges.to_a.sum(&:price).to_money * modifier.percent_ratio))
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
def update_sumaries
|
57
|
+
self.charges_sum = charges.to_a.sum(&:price).to_money
|
58
|
+
calculate_modifiers
|
59
|
+
self.discounts_sum = -@modifier_items.discounts.sum(&:price).to_money
|
60
|
+
self.surcharges_sum = @modifier_items.surcharges.sum(&:price).to_money
|
61
|
+
self.payments_sum = payments.to_a.sum(&:value).to_money
|
62
|
+
self.total = charges_sum + surcharges_sum - discounts_sum
|
63
|
+
self.balance = payments_sum - total
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Billing
|
2
|
+
class Charge < ActiveRecord::Base
|
3
|
+
include AccountItem
|
4
|
+
belongs_to :account, inverse_of: :charges, validate: true
|
5
|
+
belongs_to :chargable, polymorphic: true
|
6
|
+
monetize :price_cents
|
7
|
+
|
8
|
+
validates_presence_of :price
|
9
|
+
|
10
|
+
class << self
|
11
|
+
def args(*args)
|
12
|
+
case when args.blank? || args.first.is_a?(Hash) then
|
13
|
+
{}.merge(*args)
|
14
|
+
else
|
15
|
+
h = { price: args.shift.to_money }
|
16
|
+
args.any? ? h.merge(*args) : h
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Billing
|
2
|
+
class Modifier < ActiveRecord::Base
|
3
|
+
include AccountItem
|
4
|
+
belongs_to :account, inverse_of: :modifiers, validate: true
|
5
|
+
belongs_to :charge
|
6
|
+
monetize :fixed_value_cents
|
7
|
+
|
8
|
+
validate :percent_or_value
|
9
|
+
|
10
|
+
private
|
11
|
+
def percent_or_value
|
12
|
+
errors.add :percent_or_value, I18n.t('errors.messages.blank') if percent_ratio.blank? and fixed_value.zero?
|
13
|
+
errors.add :percent_or_value, I18n.t('errors.messages.present') if percent_ratio.present? and !fixed_value.zero?
|
14
|
+
end
|
15
|
+
|
16
|
+
class << self
|
17
|
+
def args(*args)
|
18
|
+
case when args.blank? || args.first.kind_of?(Hash) then
|
19
|
+
{}.merge(*args)
|
20
|
+
when args.first.kind_of?(String) then
|
21
|
+
d = args.shift
|
22
|
+
if d.index('%')
|
23
|
+
#TODO parse
|
24
|
+
end
|
25
|
+
else
|
26
|
+
h = { fixed_value: args.shift.to_money }
|
27
|
+
args.any? ? h.merge(*args) : h
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Billing
|
2
|
+
class Payment < ActiveRecord::Base
|
3
|
+
include AccountItem
|
4
|
+
belongs_to :account, inverse_of: :payments, validate: true
|
5
|
+
|
6
|
+
monetize :value_cents
|
7
|
+
|
8
|
+
delegate :billable, to: :account
|
9
|
+
|
10
|
+
validates_presence_of :value
|
11
|
+
|
12
|
+
after_initialize on: :create do
|
13
|
+
self.value = -account.try(:balance).to_money if value.zero?
|
14
|
+
end
|
15
|
+
|
16
|
+
class << self
|
17
|
+
def args(*args)
|
18
|
+
h = { type: 'Billing::PaymentWithType' }
|
19
|
+
case when args.blank? || args.first.kind_of?(Hash) then
|
20
|
+
args.blank? ? h : h.merge(*args)
|
21
|
+
when args.first.kind_of?(String) then
|
22
|
+
#TODO parse
|
23
|
+
else
|
24
|
+
h.merge!(payment_type_id: args.shift.to_param)
|
25
|
+
if args.any? && (args.first.kind_of?(Hash) || args.first.kind_of?(String))
|
26
|
+
h.merge(args(*args))
|
27
|
+
else
|
28
|
+
if args.blank?
|
29
|
+
h
|
30
|
+
else
|
31
|
+
h.merge!( value: args.shift.to_money )
|
32
|
+
args.any? ? h.merge(*args) : h
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module Billing
|
2
|
+
class PaymentWithType < Payment
|
3
|
+
belongs_to :payment_type, inverse_of: :payments
|
4
|
+
delegate :payment_types, to: :account
|
5
|
+
|
6
|
+
validates_presence_of :payment_type
|
7
|
+
validates :payment_type, inclusion: { in: :payment_types }
|
8
|
+
|
9
|
+
after_initialize on: :create do
|
10
|
+
self.payment_type = billable.try(:default_payment_type) unless payment_type
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
14
|
+
end
|