billing 0.0.0 → 0.0.3

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.
Files changed (125) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/billing/accounts.js +2 -0
  3. data/app/assets/javascripts/billing/charges.js +2 -0
  4. data/app/assets/javascripts/billing/modifiers.js +2 -0
  5. data/app/assets/javascripts/billing/payments.js +2 -0
  6. data/app/assets/stylesheets/billing/accounts.css +4 -0
  7. data/app/assets/stylesheets/billing/charges.css +4 -0
  8. data/app/assets/stylesheets/billing/modifiers.css +4 -0
  9. data/app/assets/stylesheets/billing/payments.css +4 -0
  10. data/app/controllers/billing/accounts_controller.rb +29 -0
  11. data/app/controllers/billing/application_controller.rb +18 -0
  12. data/app/controllers/billing/charges_controller.rb +29 -0
  13. data/app/controllers/billing/modifiers_controller.rb +29 -0
  14. data/app/controllers/billing/payments_controller.rb +29 -0
  15. data/app/helpers/billing/accounts_helper.rb +4 -0
  16. data/app/helpers/billing/charges_helper.rb +4 -0
  17. data/app/helpers/billing/modifiers_helper.rb +4 -0
  18. data/app/helpers/billing/payments_helper.rb +4 -0
  19. data/app/models/billing/account.rb +66 -0
  20. data/app/models/billing/account_item.rb +15 -0
  21. data/app/models/billing/charge.rb +21 -0
  22. data/app/models/billing/modifier.rb +32 -0
  23. data/app/models/billing/modifier_items.rb +11 -0
  24. data/app/models/billing/origin.rb +4 -0
  25. data/app/models/billing/payment.rb +39 -0
  26. data/app/models/billing/payment_type.rb +6 -0
  27. data/app/models/billing/payment_with_type.rb +14 -0
  28. data/app/models/billing/plu.rb +4 -0
  29. data/app/models/billing/profile.rb +4 -0
  30. data/app/models/billing/tax_group.rb +4 -0
  31. data/app/views/billing/accounts/index.html.erb +7 -0
  32. data/app/views/billing/accounts/new.html.erb +8 -0
  33. data/app/views/billing/accounts/show.html.erb +29 -0
  34. data/app/views/billing/application/index.html.erb +3 -0
  35. data/app/views/billing/charges/new.html.erb +12 -0
  36. data/app/views/billing/modifiers/new.html.erb +18 -0
  37. data/app/views/billing/payments/new.html.erb +11 -0
  38. data/config/routes.rb +6 -0
  39. data/db/migrate/20140717180443_create_billing_accounts.rb +9 -0
  40. data/db/migrate/20140717181134_create_billing_charges.rb +11 -0
  41. data/db/migrate/20140717181406_create_billing_discounts.rb +11 -0
  42. data/db/migrate/20140717183129_create_billing_payments.rb +10 -0
  43. data/db/migrate/20140717202527_create_billing_origins.rb +9 -0
  44. data/db/migrate/20140718164841_add_sumaries_to_billing_account.rb +11 -0
  45. data/db/migrate/20140718210349_add_fixed_value_to_billing_discount.rb +7 -0
  46. data/db/migrate/20140718212116_create_billing_payment_types.rb +11 -0
  47. data/db/migrate/20140719094023_create_billing_tax_groups.rb +9 -0
  48. data/db/migrate/20140719094033_create_billing_plus.rb +9 -0
  49. data/db/migrate/20140719094418_create_billing_profiles.rb +9 -0
  50. data/db/migrate/20140719103621_rename_billing_discounts_to_modifiers.rb +5 -0
  51. data/db/migrate/20140719110412_add_surcharges_sum_to_billing_account.rb +7 -0
  52. data/db/migrate/20140720110811_add_type_to_billing_payment.rb +6 -0
  53. data/db/migrate/20140720132559_add_type_to_billing_payment_type.rb +5 -0
  54. data/lib/billing.rb +16 -0
  55. data/lib/billing/billable.rb +34 -0
  56. data/lib/billing/engine.rb +1 -0
  57. data/lib/billing/mapping.rb +32 -0
  58. data/lib/billing/routes.rb +16 -0
  59. data/lib/billing/version.rb +1 -1
  60. data/lib/tasks/billing.rake +7 -0
  61. data/test/controllers/billing/accounts_controller_test.rb +19 -0
  62. data/test/controllers/billing/charges_controller_test.rb +16 -0
  63. data/test/controllers/billing/modifiers_controller_test.rb +16 -0
  64. data/test/controllers/billing/payments_controller_test.rb +16 -0
  65. data/test/dummy/app/models/profile.rb +3 -0
  66. data/test/dummy/config/routes.rb +3 -2
  67. data/test/dummy/db/development.sqlite3 +0 -0
  68. data/test/dummy/db/migrate/20140718104656_create_profiles.rb +8 -0
  69. data/test/dummy/db/schema.rb +112 -0
  70. data/test/dummy/db/test.sqlite3 +0 -0
  71. data/test/dummy/log/development.log +1602 -0
  72. data/test/dummy/log/test.log +52069 -0
  73. data/test/dummy/test/fixtures/profiles.yml +11 -0
  74. data/test/dummy/test/models/profile_test.rb +7 -0
  75. data/test/dummy/tmp/cache/assets/test/sprockets/02adf8ace512aefc4ef19b35aebc07f7 +0 -0
  76. data/test/dummy/tmp/cache/assets/test/sprockets/0cab887466527f5353fd43adab72769b +0 -0
  77. data/test/dummy/tmp/cache/assets/test/sprockets/25b7c6efcbd128f109577104af58d084 +0 -0
  78. data/test/dummy/tmp/cache/assets/test/sprockets/2f52090f9e08ac02cd453b04af0df887 +0 -0
  79. data/test/dummy/tmp/cache/assets/test/sprockets/35a523ac3c33d6409a69faead4b2a882 +0 -0
  80. data/test/dummy/tmp/cache/assets/test/sprockets/3f4fc67be1dd91962f5a0026848dca77 +0 -0
  81. data/test/dummy/tmp/cache/assets/test/sprockets/43b3cc0ac6f63c0e1a3ab61fec84519d +0 -0
  82. data/test/dummy/tmp/cache/assets/test/sprockets/59435066fc40e1ef5b45b0fd2c0eacf9 +0 -0
  83. data/test/dummy/tmp/cache/assets/test/sprockets/69cb965e6031d8099c185256f6fa8f90 +0 -0
  84. data/test/dummy/tmp/cache/assets/test/sprockets/6d34e4addaf3495d1d96306d164feb97 +0 -0
  85. data/test/dummy/tmp/cache/assets/test/sprockets/79316f9f3f5ebcec9b368d92d2e97e23 +0 -0
  86. data/test/dummy/tmp/cache/assets/test/sprockets/7ffc7e805e3fc08bae6a93e027a3e911 +0 -0
  87. data/test/dummy/tmp/cache/assets/test/sprockets/82ae0f4fbceb673c729b9bcb54a1161c +0 -0
  88. data/test/dummy/tmp/cache/assets/test/sprockets/9509747efe602f6a81d50d9744f385f2 +0 -0
  89. data/test/dummy/tmp/cache/assets/test/sprockets/971b6b8d6c7a57e72d235e55537a2c44 +0 -0
  90. data/test/dummy/tmp/cache/assets/test/sprockets/b68d1e1a967e74abe3e10f643756ae67 +0 -0
  91. data/test/dummy/tmp/cache/assets/test/sprockets/cab3eca4515d1263ea8db2ff58df151d +0 -0
  92. data/test/dummy/tmp/cache/assets/test/sprockets/cac68bb014ecc482b8f85312e49baa6f +0 -0
  93. data/test/dummy/tmp/cache/assets/test/sprockets/d3ab844c61f1c211ed5fad5407cd18ef +0 -0
  94. data/test/dummy/tmp/cache/assets/test/sprockets/d6d844128e4910cf773d1c48dd147e3b +0 -0
  95. data/test/dummy/tmp/cache/assets/test/sprockets/e62907e54633a2adb53c33c1f59b79bf +0 -0
  96. data/test/dummy/tmp/cache/assets/test/sprockets/e96b4e8fe0ebcceb51d202c8af7826ea +0 -0
  97. data/test/dummy/tmp/cache/assets/test/sprockets/eb95e26896c1c6788657c4ef68a7e9e1 +0 -0
  98. data/test/dummy/tmp/cache/assets/test/sprockets/efaa0abeb4ad44b0ef8df996631f3997 +0 -0
  99. data/test/dummy/tmp/cache/assets/test/sprockets/f393277b28dd79320611f18a379dbea7 +0 -0
  100. data/test/dummy/tmp/cache/assets/test/sprockets/fbf1489a0c3d66a329f070c10cd77a03 +0 -0
  101. data/test/fixtures/billing/accounts.yml +11 -0
  102. data/test/fixtures/billing/charges.yml +15 -0
  103. data/test/fixtures/billing/modifiers.yml +14 -0
  104. data/test/fixtures/billing/origins.yml +7 -0
  105. data/test/fixtures/billing/payment_types.yml +11 -0
  106. data/test/fixtures/billing/payments.yml +15 -0
  107. data/test/fixtures/billing/plus.yml +7 -0
  108. data/test/fixtures/billing/profiles.yml +7 -0
  109. data/test/fixtures/billing/tax_groups.yml +7 -0
  110. data/test/fixtures/profiles.yml +1 -0
  111. data/test/helpers/billing/accounts_helper_test.rb +6 -0
  112. data/test/helpers/billing/charges_helper_test.rb +6 -0
  113. data/test/helpers/billing/modifiers_helper_test.rb +6 -0
  114. data/test/helpers/billing/payments_helper_test.rb +6 -0
  115. data/test/models/billing/account_test.rb +43 -0
  116. data/test/models/billing/charge_test.rb +17 -0
  117. data/test/models/billing/modifier_test.rb +19 -0
  118. data/test/models/billing/origin_test.rb +9 -0
  119. data/test/models/billing/payment_test.rb +17 -0
  120. data/test/models/billing/payment_type_test.rb +9 -0
  121. data/test/models/billing/plu_test.rb +9 -0
  122. data/test/models/billing/profile_test.rb +9 -0
  123. data/test/models/billing/tax_group_test.rb +9 -0
  124. data/test/test_helper.rb +28 -2
  125. metadata +199 -7
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5aa137f6c716e99d88ef6db1a1410aabc8c26b96
4
- data.tar.gz: fa42f7b09a684b283cf3caf489d42831c234d791
3
+ metadata.gz: 747d5529859b70e9cc69f11653785d07d55b74a4
4
+ data.tar.gz: cfc4af81e2d5e2361a2bea947e7e2bb3cdc251f2
5
5
  SHA512:
6
- metadata.gz: aed8c76f8a207cdf0fa32ced918be5a6373ef3f8aa428dc3e3c8db1bac8302435c047655e30ffbcfe27dc9214eba0c896d69ec39765cba03ac0182edd75cc62d
7
- data.tar.gz: a5c268cfdc08100fc98ba92f83a6ef752b9847a1b496b5fb53a564e8c99b3a28ea560543789b09118f9a8fd8f0209005c05e8bbadf1aa6848813caeca6eab88a
6
+ metadata.gz: c6c723a641929e19b86cd4bbfd1e175606036f055ba0112691c82c5e573b08bbc411133c6c577aef41655859e85a100a26b5ed60ed3c6e7bd8a6f3c6d9b7f535
7
+ data.tar.gz: c6d5372d0418f727050175f5eddf78c67f2cf903545722a593e4c9a6bb2bab8342c769cfd9a4d21a3741ed40053dfa4d3d341483ad157606e83c3381b72bebdf
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -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,4 @@
1
+ module Billing
2
+ module AccountsHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Billing
2
+ module ChargesHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Billing
2
+ module ModifiersHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Billing
2
+ module PaymentsHelper
3
+ end
4
+ 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,15 @@
1
+ module Billing
2
+ module AccountItem
3
+ extend ActiveSupport::Concern
4
+
5
+ included do
6
+ #belongs_to :account
7
+
8
+ delegate :save, to: :account, prefix: :account
9
+ after_save :account_save
10
+
11
+ validates_presence_of :account
12
+ end
13
+
14
+ end
15
+ 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,11 @@
1
+ module Billing
2
+ class ModifierItems < Array
3
+ def discounts
4
+ select{ |m| m.price < 0 }
5
+ end
6
+
7
+ def surcharges
8
+ select{ |m| m.price > 0 }
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,4 @@
1
+ module Billing
2
+ class Origin < ActiveRecord::Base
3
+ end
4
+ 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,6 @@
1
+ module Billing
2
+ class PaymentType < ActiveRecord::Base
3
+ has_many :payments
4
+ validates_presence_of :name
5
+ end
6
+ 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