billing 0.0.4d → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (77) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/billing/accounts.js +2 -0
  3. data/app/assets/javascripts/billing/application.js +13 -0
  4. data/app/assets/javascripts/billing/charges.js +2 -0
  5. data/app/assets/javascripts/billing/modifiers.js +2 -0
  6. data/app/assets/stylesheets/billing/accounts.css +4 -0
  7. data/app/assets/stylesheets/billing/application.css +15 -0
  8. data/app/assets/stylesheets/billing/charges.css +4 -0
  9. data/app/assets/stylesheets/billing/modifiers.css +4 -0
  10. data/app/assets/stylesheets/billing/payments.css +4 -0
  11. data/app/controllers/billing/accounts_controller.rb +29 -0
  12. data/app/controllers/billing/application_controller.rb +22 -0
  13. data/app/controllers/billing/charges_controller.rb +29 -0
  14. data/app/controllers/billing/modifiers_controller.rb +29 -0
  15. data/app/controllers/billing/payments_controller.rb +29 -0
  16. data/app/helpers/billing/accounts_helper.rb +4 -0
  17. data/app/helpers/billing/application_helper.rb +4 -0
  18. data/app/helpers/billing/charges_helper.rb +4 -0
  19. data/app/helpers/billing/modifiers_helper.rb +4 -0
  20. data/app/helpers/billing/payments_helper.rb +4 -0
  21. data/app/models/billing/{bill.rb → account.rb} +30 -37
  22. data/app/models/billing/charge.rb +11 -25
  23. data/app/models/billing/modifier.rb +5 -5
  24. data/app/models/billing/origin.rb +2 -7
  25. data/app/models/billing/payment.rb +11 -8
  26. data/app/models/billing/payment_with_type.rb +1 -1
  27. data/app/models/billing/report.rb +12 -23
  28. data/app/models/concerns/billing/{bill_item.rb → account_item.rb} +6 -5
  29. data/app/views/billing/accounts/index.html.erb +7 -0
  30. data/app/views/billing/accounts/new.html.erb +8 -0
  31. data/app/views/billing/accounts/show.html.erb +29 -0
  32. data/app/views/billing/application/index.html.erb +3 -0
  33. data/app/views/billing/charges/new.html.erb +12 -0
  34. data/app/views/billing/modifiers/new.html.erb +18 -0
  35. data/app/views/billing/payments/new.html.erb +11 -0
  36. data/app/views/layouts/billing/application.html.erb +14 -0
  37. data/config/routes.rb +6 -1
  38. data/lib/billing.rb +2 -0
  39. data/lib/billing/billable.rb +3 -3
  40. data/lib/billing/engine.rb +0 -3
  41. data/lib/billing/mapping.rb +32 -0
  42. data/lib/billing/routes.rb +16 -0
  43. data/lib/billing/version.rb +1 -1
  44. data/test/controllers/billing/accounts_controller_test.rb +19 -0
  45. data/test/controllers/billing/charges_controller_test.rb +16 -0
  46. data/test/controllers/billing/modifiers_controller_test.rb +16 -0
  47. data/test/controllers/billing/payments_controller_test.rb +16 -0
  48. data/test/dummy/config/routes.rb +3 -1
  49. data/test/dummy/db/development.sqlite3 +0 -0
  50. data/test/dummy/db/schema.rb +17 -23
  51. data/test/dummy/db/test.sqlite3 +0 -0
  52. data/test/dummy/log/development.log +0 -8144
  53. data/test/dummy/log/test.log +0 -64325
  54. data/test/fixtures/billing/{bills.yml → accounts.yml} +0 -0
  55. data/test/fixtures/billing/charges.yml +2 -2
  56. data/test/fixtures/billing/modifiers.yml +2 -2
  57. data/test/fixtures/billing/payments.yml +2 -2
  58. data/test/helpers/billing/accounts_helper_test.rb +6 -0
  59. data/test/helpers/billing/charges_helper_test.rb +6 -0
  60. data/test/helpers/billing/modifiers_helper_test.rb +6 -0
  61. data/test/helpers/billing/payments_helper_test.rb +6 -0
  62. data/test/integration/navigation_test.rb +10 -0
  63. data/test/models/billing/account_test.rb +56 -0
  64. data/test/models/billing/charge_test.rb +6 -13
  65. data/test/models/billing/modifier_test.rb +2 -2
  66. data/test/models/billing/payment_test.rb +12 -12
  67. metadata +58 -20
  68. data/app/models/billing/room_transfer.rb +0 -4
  69. data/app/models/concerns/billing/bill_text_parser.rb +0 -18
  70. data/config/initializers/money.rb +0 -67
  71. data/db/migrate/20140803073707_rename_billing_account_to_bill.rb +0 -8
  72. data/db/migrate/20140804065726_add_qty_to_billing_charge.rb +0 -5
  73. data/db/migrate/20140804070517_add_tax_ratio_to_billing_charge.rb +0 -5
  74. data/db/migrate/20141001185321_add_transfer_device_to_billing_origin.rb +0 -5
  75. data/db/migrate/20141027235427_add_f_amount_to_billing_report.rb +0 -7
  76. data/lib/collection_proxy_wild.rb +0 -9
  77. data/test/models/billing/bill_test.rb +0 -76
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ca16dec983eeeea4ce9b20cd27e90de954c4ea13
4
- data.tar.gz: 6dd48dd7320540e7fdb111673a88087489731e85
3
+ metadata.gz: f6a8b7a29cfa69d401eb731dbb4dcc67a9016d5e
4
+ data.tar.gz: 4ef3454d28c7e0b42f9bb55108131baad90d7ef4
5
5
  SHA512:
6
- metadata.gz: 4faaa4ce8278d8e8a8e448c2e30ee00c7a51e0c8d37b56a93f7737aea366c93589b31d7cedd39b8000b1c51fb844ee0cfa3e737a29ff6ac318619576f5a2289a
7
- data.tar.gz: 65471f1a0ccb28af1936255efa2a841c536e588639cfaaed0c07363503cb1d7aa17b064abe4ef5108d0b4efa7cd7783e5545b7384ef01ba22efa3f7a1d290468
6
+ metadata.gz: 1c2f6ff8668e4f23630342d787596721706900dc4dfe9b2aa5f33552774fa42f6f165912b456ec220d0866fe68f9bb06ceb64ba79bb4c52d3a3f3a5a361d8d5f
7
+ data.tar.gz: 5e39901f8155e9a73206311bd4bea98417856e366456868579cc2be1ee3717f660c3cb625ac445e9321fee0317ae55fa587dc13d39756bd9c17c14ddae0255e0
@@ -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,13 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // compiled file.
9
+ //
10
+ // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
11
+ // about supported directives.
12
+ //
13
+ //= require_tree .
@@ -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,15 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9
+ * compiled file so the styles you add here take precedence over styles defined in any styles
10
+ * defined in the other CSS/SCSS files in this directory. It is generally better to create a new
11
+ * file per style scope.
12
+ *
13
+ *= require_tree .
14
+ *= require_self
15
+ */
@@ -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
@@ -0,0 +1,22 @@
1
+ module Billing
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
21
+ end
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 ApplicationHelper
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
@@ -1,5 +1,5 @@
1
1
  module Billing
2
- class Bill < ActiveRecord::Base
2
+ class Account < ActiveRecord::Base
3
3
  acts_as_paranoid if respond_to?(:acts_as_paranoid)
4
4
  has_paper_trail class_name: 'Billing::Version' if respond_to?(:has_paper_trail)
5
5
 
@@ -11,11 +11,11 @@ module Billing
11
11
  monetize :balance_cents
12
12
 
13
13
  belongs_to :billable, polymorphic: true
14
- has_many :charges, inverse_of: :bill, dependent: :destroy
15
- has_many :modifiers, inverse_of: :bill, dependent: :destroy
16
- has_many :payments, inverse_of: :bill, dependent: :restrict_with_error
17
- belongs_to :origin, inverse_of: :bills
18
- belongs_to :report, inverse_of: :bills
14
+ has_many :charges, inverse_of: :account, dependent: :destroy
15
+ has_many :modifiers, inverse_of: :account, dependent: :destroy
16
+ has_many :payments, inverse_of: :account, dependent: :restrict_with_error
17
+ belongs_to :origin, inverse_of: :accounts
18
+ belongs_to :report, inverse_of: :accounts
19
19
 
20
20
  if defined? Extface
21
21
  belongs_to :extface_job, class_name: 'Extface::Job'
@@ -28,14 +28,11 @@ module Billing
28
28
  scope :unpaid, -> { where(arel_table[:balance_cents].lt(0)) }
29
29
  scope :open, -> { where.not(balance_cents: 0) }
30
30
  scope :partially_paid, -> { where.not( payments_sum_cents: 0, balance_cents: 0 ) }
31
- scope :for_report, -> { where(balance_cents: 0 ,report_id: nil) }
32
31
 
33
- before_validation do
34
- update_sumaries
35
- self.origin = payments.first.try(:origin) unless origin.present? or payments.many?
36
- end
37
- before_create do
38
- self.number = "#{billable.id}:#{billable.billing_bills.count}"
32
+ before_validation :update_sumaries
33
+
34
+ before_save on: :create do
35
+ self.number = "#{billable.id}:#{billable.billing_accounts.count}"
39
36
  self.name = "B:#{number}" if name.nil?
40
37
  end
41
38
  before_save :perform_autofin, if: :becomes_paid?
@@ -48,15 +45,18 @@ module Billing
48
45
  :payments_of_diff_fiscalization?, :multiple_cash_payments?, if: :has_payments?
49
46
 
50
47
  def charge(*args)
51
- charges.wild *args
48
+ c = charges.new Charge.args(*args)
49
+ c if c.save
52
50
  end
53
51
 
54
52
  def modify(*args)
55
- modifiers.wild *args
53
+ m = modifiers.new Modifier.args(*args)
54
+ m if m.save
56
55
  end
57
56
 
58
57
  def pay(*args)
59
- payments.wild *args
58
+ p = build_typed_payment Payment.args(*args)
59
+ p if p.save
60
60
  end
61
61
 
62
62
  def modifier_items
@@ -80,8 +80,7 @@ module Billing
80
80
  end
81
81
 
82
82
  def build_typed_payment(attributes = {})
83
- payment_origin = attributes[:origin] || origins.find_by_id(attributes[:origin_id])
84
- payments.new(attributes.merge(type: (payment_origin || origin).try(:payment_model) || 'Billing::PaymentWithType'))
83
+ payments.new(attributes.merge(type: origin.try(:payment_model) || 'Billing::PaymentWithType'))
85
84
  end
86
85
 
87
86
  def fiscalize #TODO test
@@ -91,29 +90,24 @@ module Billing
91
90
 
92
91
  private
93
92
  def calculate_modifiers
94
- charges_a = charges.to_a
95
93
  @modifier_items = ModifierItems.new.tap() do |items|
96
- modifiers.select{ |m| m.charge.present? }.each do |charge_modifier|
97
- charge = charges_a.find{ |c| c == charge_modifier.charge }
98
- mod_value = charge_modifier.percent_ratio.nil? ? charge_modifier.fixed_value : (charge_modifier.charge.price * charge_modifier.percent_ratio)
99
- p mod_value
100
- charge.value = charge.price + mod_value
101
- #p charge.value
102
- #p "-"
103
- items << Charge.new(price: mod_value, chargable: charge)
104
- end
105
- modifiers.select{ |m| m.charge.nil? }.each do |global_modifier|
106
- items << Charge.new(price: global_modifier.percent_ratio.nil? ? global_modifier.fixed_value : (charges_a.sum(&:value).to_money * global_modifier.percent_ratio))
94
+ modifiers.each do |modifier|
95
+ if charge = modifier.charge
96
+ charge.value = modifier.percent_ratio.nil? ? modifier.fixed_value : (charge.price * modifier.percent_ratio)
97
+ items << Charge.new(price: charge.value, chargable: charge)
98
+ else
99
+ items << Charge.new(price: modifier.percent_ratio.nil? ? modifier.fixed_value : (charges.to_a.sum(&:price).to_money * modifier.percent_ratio))
100
+ end
107
101
  end
108
102
  end
109
103
  end
110
104
  def update_sumaries
105
+ self.charges_sum = charges.to_a.sum(&:price).to_money
111
106
  calculate_modifiers
112
- self.charges_sum = charges.to_a.sum(0.to_money, &:value).to_money
113
- self.discounts_sum = @modifier_items.discounts.sum(0.to_money, &:price).to_money
114
- self.surcharges_sum = @modifier_items.surcharges.sum(0.to_money, &:price).to_money
115
- self.payments_sum = payments.to_a.sum(0.to_money, &:value).to_money
116
- self.total = charges.to_a.sum(0.to_money, &:price) + surcharges_sum + discounts_sum
107
+ self.discounts_sum = -@modifier_items.discounts.sum(&:price).to_money
108
+ self.surcharges_sum = @modifier_items.surcharges.sum(&:price).to_money
109
+ self.payments_sum = payments.to_a.sum(&:value).to_money
110
+ self.total = charges_sum + surcharges_sum - discounts_sum
117
111
  self.balance = payments_sum - total
118
112
  end
119
113
 
@@ -144,8 +138,7 @@ module Billing
144
138
  end
145
139
 
146
140
  def fiscalizable?
147
- payments.select(&:fiscal?).any?
141
+ payments.select(&:fiscal?)
148
142
  end
149
-
150
143
  end
151
144
  end
@@ -1,48 +1,34 @@
1
1
  module Billing
2
2
  class Charge < ActiveRecord::Base
3
- include BillItem
4
-
5
- attr_accessor :tax_group, :plu, :department
6
-
7
- belongs_to :bill, inverse_of: :charges, validate: true
3
+ include AccountItem
4
+ belongs_to :account, inverse_of: :charges, validate: true
8
5
  belongs_to :chargable, polymorphic: true
9
6
  belongs_to :origin, inverse_of: :charges
10
7
  has_one :modifier, inverse_of: :charge
11
8
 
12
- monetize :price_cents, with_model_currency: :price_currency
9
+ monetize :price_cents
13
10
  monetize :value_cents
14
11
 
15
- delegate :paid?, to: :bill
12
+ delegate :paid?, to: :account
16
13
 
17
- scope :unpaid, -> { joins(:bill).where.not(billing_bills: { balance_cents: 0}) }
18
- scope :paid, -> { joins(:bill).where(billing_bills: { balance_cents: 0}) }
14
+ scope :unpaid, -> { joins(:account).where.not(billing_accounts: { balance_cents: 0}) }
15
+ scope :paid, -> { joins(:account).where(billing_accounts: { balance_cents: 0}) }
19
16
  scope :in_period, lambda {|from, to| where(revenue_at: from..to) }
20
17
 
21
18
  validates_presence_of :price
22
19
  validates_numericality_of :value, greater_than_or_equal_to: 0
23
20
 
24
- after_initialize do
25
- self.value = price #unless modifier.present? #bill validation will update modified value
21
+ before_save do
22
+ self.value = price unless modifier.present? #FIXME global account modifier lost
26
23
  end
27
24
 
28
25
  class << self
29
- include Billing::BillTextParser
30
- def wild_args(*args)
26
+ def args(*args)
31
27
  case when args.blank? || args.first.is_a?(Hash) then
32
- return {}.merge(*args)
33
- when args.size == 1 && args.first.is_a?(String) then
34
- if match = args.shift.match(/(\d+[.,]\d+\*|\d+\*|)(\d+[.,]\d+[A-Z]*|\d+[A-Z]*|)(#\d+|)(@\d+|)([+-]\d+[.,]\d+\%?|[+-]\d+\%?|)(\/\S+|)/)
35
- qty_s, price_s, plu_s, tax_group_s, mod_s, text = match.captures
36
- return {
37
- qty: parse_qty(qty_s),
38
- price: price_s.to_money,
39
- plu: parse_plu(plu_s),
40
- name: parse_text(text)
41
- }
42
- end
28
+ {}.merge(*args)
43
29
  else
44
30
  h = { price: args.shift.to_money }
45
- return args.any? ? h.merge(*args) : h
31
+ args.any? ? h.merge(*args) : h
46
32
  end
47
33
  end
48
34
  end