billing 0.0.4d → 0.0.4
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/application.js +13 -0
- data/app/assets/javascripts/billing/charges.js +2 -0
- data/app/assets/javascripts/billing/modifiers.js +2 -0
- data/app/assets/stylesheets/billing/accounts.css +4 -0
- data/app/assets/stylesheets/billing/application.css +15 -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 +22 -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/application_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/{bill.rb → account.rb} +30 -37
- data/app/models/billing/charge.rb +11 -25
- data/app/models/billing/modifier.rb +5 -5
- data/app/models/billing/origin.rb +2 -7
- data/app/models/billing/payment.rb +11 -8
- data/app/models/billing/payment_with_type.rb +1 -1
- data/app/models/billing/report.rb +12 -23
- data/app/models/concerns/billing/{bill_item.rb → account_item.rb} +6 -5
- 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/app/views/layouts/billing/application.html.erb +14 -0
- data/config/routes.rb +6 -1
- data/lib/billing.rb +2 -0
- data/lib/billing/billable.rb +3 -3
- data/lib/billing/engine.rb +0 -3
- data/lib/billing/mapping.rb +32 -0
- data/lib/billing/routes.rb +16 -0
- data/lib/billing/version.rb +1 -1
- 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/config/routes.rb +3 -1
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/db/schema.rb +17 -23
- data/test/dummy/db/test.sqlite3 +0 -0
- data/test/dummy/log/development.log +0 -8144
- data/test/dummy/log/test.log +0 -64325
- data/test/fixtures/billing/{bills.yml → accounts.yml} +0 -0
- data/test/fixtures/billing/charges.yml +2 -2
- data/test/fixtures/billing/modifiers.yml +2 -2
- data/test/fixtures/billing/payments.yml +2 -2
- 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/integration/navigation_test.rb +10 -0
- data/test/models/billing/account_test.rb +56 -0
- data/test/models/billing/charge_test.rb +6 -13
- data/test/models/billing/modifier_test.rb +2 -2
- data/test/models/billing/payment_test.rb +12 -12
- metadata +58 -20
- data/app/models/billing/room_transfer.rb +0 -4
- data/app/models/concerns/billing/bill_text_parser.rb +0 -18
- data/config/initializers/money.rb +0 -67
- data/db/migrate/20140803073707_rename_billing_account_to_bill.rb +0 -8
- data/db/migrate/20140804065726_add_qty_to_billing_charge.rb +0 -5
- data/db/migrate/20140804070517_add_tax_ratio_to_billing_charge.rb +0 -5
- data/db/migrate/20141001185321_add_transfer_device_to_billing_origin.rb +0 -5
- data/db/migrate/20141027235427_add_f_amount_to_billing_report.rb +0 -7
- data/lib/collection_proxy_wild.rb +0 -9
- data/test/models/billing/bill_test.rb +0 -76
@@ -1,13 +1,13 @@
|
|
1
1
|
module Billing
|
2
2
|
class Modifier < ActiveRecord::Base
|
3
|
-
include
|
4
|
-
belongs_to :
|
3
|
+
include AccountItem
|
4
|
+
belongs_to :account, inverse_of: :modifiers, validate: true
|
5
5
|
belongs_to :charge, inverse_of: :modifier
|
6
6
|
monetize :fixed_value_cents
|
7
7
|
|
8
8
|
validate :percent_or_value
|
9
|
-
validates_uniqueness_of :charge, scope: :
|
10
|
-
validates_uniqueness_of :
|
9
|
+
validates_uniqueness_of :charge, scope: :account_id, allow_nil: true
|
10
|
+
validates_uniqueness_of :account, scope: :charge_id
|
11
11
|
|
12
12
|
private
|
13
13
|
def percent_or_value
|
@@ -16,7 +16,7 @@ module Billing
|
|
16
16
|
end
|
17
17
|
|
18
18
|
class << self
|
19
|
-
def
|
19
|
+
def args(*args)
|
20
20
|
case when args.blank? || args.first.kind_of?(Hash) then
|
21
21
|
{}.merge(*args)
|
22
22
|
when args.first.kind_of?(String) then
|
@@ -1,11 +1,10 @@
|
|
1
1
|
module Billing
|
2
2
|
class Origin < ActiveRecord::Base
|
3
|
-
has_many :
|
3
|
+
has_many :accounts, inverse_of: :origin
|
4
4
|
has_many :charges, inverse_of: :origin
|
5
|
-
has_many :payments, through: :
|
5
|
+
has_many :payments, through: :accounts
|
6
6
|
if defined? Extface
|
7
7
|
belongs_to :fiscal_device, ->(o) { where( extfaceable_id: o.master_id ) }, class_name: 'Extface::Device'
|
8
|
-
belongs_to :transfer_device, ->(o) { where( extfaceable_id: o.master_id ) }, class_name: 'Extface::Device'
|
9
8
|
end
|
10
9
|
|
11
10
|
validates_presence_of :name
|
@@ -14,9 +13,5 @@ module Billing
|
|
14
13
|
def external_payment?
|
15
14
|
payment_model != Payment::PAYMENT_WITH_TYPE
|
16
15
|
end
|
17
|
-
|
18
|
-
def room_transfer?
|
19
|
-
payment_model == Payment::ROOM_TRANSFER
|
20
|
-
end
|
21
16
|
end
|
22
17
|
end
|
@@ -3,31 +3,34 @@ module Billing
|
|
3
3
|
PAYMENT_WITH_TYPE = 'Billing::PaymentWithType'.freeze
|
4
4
|
PAYMENT_EXTERNAL = 'Billing::PaymentExternal'.freeze
|
5
5
|
PAYPAL_EXPRESS = 'Billing::PaypalExpress'.freeze
|
6
|
-
|
7
|
-
PAYMENT_MODELS = [PAYMENT_WITH_TYPE, PAYMENT_EXTERNAL, PAYPAL_EXPRESS, ROOM_TRANSFER].freeze
|
6
|
+
PAYMENT_MODELS = [PAYMENT_WITH_TYPE, PAYMENT_EXTERNAL, PAYPAL_EXPRESS].freeze
|
8
7
|
|
9
|
-
include
|
8
|
+
include AccountItem
|
10
9
|
|
11
10
|
attr_writer :origin
|
12
11
|
attr_accessor :origin_id
|
13
12
|
monetize :value_cents
|
14
13
|
|
15
|
-
belongs_to :
|
14
|
+
belongs_to :account, inverse_of: :payments, validate: true
|
16
15
|
|
17
16
|
scope :in_period, lambda {|from, to| where(created_at: from..to) }
|
18
|
-
scope :for_report, -> { joins(:
|
17
|
+
scope :for_report, -> { joins(:account).where(billing_accounts: { balance_cents: 0 ,report_id: nil }) }
|
19
18
|
|
20
19
|
if defined? Extface
|
21
20
|
belongs_to :extface_job, class_name: 'Extface::Job'
|
22
21
|
end
|
23
22
|
|
24
|
-
delegate :billable, to: :
|
23
|
+
delegate :billable, to: :account
|
25
24
|
|
26
25
|
validates_numericality_of :value, greater_than_or_equal_to: 0
|
27
26
|
validates :type, inclusion: { in: PAYMENT_MODELS }
|
28
27
|
|
29
28
|
after_initialize on: :create do
|
30
|
-
self.value = -
|
29
|
+
self.value = -account.try(:balance) if value.zero?
|
30
|
+
end
|
31
|
+
|
32
|
+
before_validation do
|
33
|
+
account.origin = origin unless account.origin and account.payments.many?
|
31
34
|
end
|
32
35
|
|
33
36
|
def fiscal?; false; end
|
@@ -40,7 +43,7 @@ module Billing
|
|
40
43
|
|
41
44
|
private
|
42
45
|
class << self
|
43
|
-
def
|
46
|
+
def args(*args)
|
44
47
|
h = {}
|
45
48
|
case when args.blank? || args.first.kind_of?(Hash) then
|
46
49
|
args.blank? ? h : h.merge(*args)
|
@@ -3,31 +3,26 @@ module Billing
|
|
3
3
|
FISCAL_X_REPORT = 'x_report'.freeze
|
4
4
|
FISCAL_Z_REPORT = 'z_report'.freeze
|
5
5
|
FISCAL_PERIOD_REPORT = 'period_report'.freeze
|
6
|
-
|
7
|
-
F_OPERATIONS = [FISCAL_X_REPORT, FISCAL_Z_REPORT, FISCAL_PERIOD_REPORT, FISCAL_PAYED_RECVD].freeze
|
6
|
+
F_OPERATIONS = [FISCAL_X_REPORT, FISCAL_Z_REPORT, FISCAL_PERIOD_REPORT].freeze
|
8
7
|
|
9
8
|
has_paper_trail class_name: 'Billing::Version'
|
10
9
|
belongs_to :origin, inverse_of: :reports
|
11
|
-
has_many :
|
10
|
+
has_many :accounts, inverse_of: :report, autosave: true
|
12
11
|
belongs_to :extface_job, class_name: 'Extface::Job'
|
13
|
-
has_many :payments, through: :
|
12
|
+
has_many :payments, through: :accounts
|
14
13
|
|
15
14
|
monetize :payments_sum_cents
|
16
15
|
monetize :payments_cash_cents
|
17
16
|
monetize :payments_fiscal_cents
|
18
|
-
monetize :f_amount_cents
|
19
17
|
|
20
18
|
validates_presence_of :origin
|
21
|
-
validates_absence_of :
|
19
|
+
validates_absence_of :partially_paid_accounts?
|
22
20
|
validates :f_operation, inclusion: { in: F_OPERATIONS }, allow_nil: true
|
23
21
|
validates_presence_of :f_period_from, :f_period_to, if: :fiscal_period_report?
|
24
|
-
validates_presence_of :f_amount, if: :fiscal_payed_recvd?
|
25
22
|
|
26
|
-
before_validation :
|
23
|
+
before_validation :set_report_to_accounts
|
27
24
|
before_create :update_summary
|
28
25
|
|
29
|
-
scope :in_period, lambda {|from, to| where(created_at: from..to) }
|
30
|
-
|
31
26
|
|
32
27
|
def fiscalization
|
33
28
|
if origin.fiscal_device.present?
|
@@ -42,18 +37,14 @@ module Billing
|
|
42
37
|
f_operation == FISCAL_PERIOD_REPORT
|
43
38
|
end
|
44
39
|
|
45
|
-
def
|
46
|
-
|
47
|
-
end
|
48
|
-
|
49
|
-
def set_report_to_bills
|
50
|
-
self.bills << origin.bills.for_report if zeroing?
|
40
|
+
def set_report_to_accounts
|
41
|
+
self.accounts << origin.accounts.select(&:paid?) if zeroing?
|
51
42
|
end
|
52
43
|
|
53
44
|
def update_summary
|
54
|
-
self.payments_sum =
|
55
|
-
self.payments_cash =
|
56
|
-
self.payments_fiscal =
|
45
|
+
self.payments_sum = accounts.to_a.sum(Money.new(0, 'USD'), &:payments_sum)
|
46
|
+
self.payments_cash = payments.select{ |p| p.try(:cash?) }.sum(Money.new(0, 'USD'), &:value)
|
47
|
+
self.payments_fiscal = payments.select{ |p| p.try(:fiscal?) }.sum(Money.new(0, 'USD'), &:value)
|
57
48
|
perform_fiscal_job
|
58
49
|
end
|
59
50
|
|
@@ -65,13 +56,11 @@ module Billing
|
|
65
56
|
self.extface_job = origin.fiscal_device.driver.x_report_session
|
66
57
|
when FISCAL_PERIOD_REPORT then
|
67
58
|
p "period"
|
68
|
-
when FISCAL_PAYED_RECVD then
|
69
|
-
self.extface_job = origin.fiscal_device.driver.payed_recv_account(f_amount.to_f)
|
70
59
|
end
|
71
60
|
end
|
72
61
|
|
73
|
-
def
|
74
|
-
|
62
|
+
def partially_paid_accounts?
|
63
|
+
accounts.partially_paid.any?
|
75
64
|
end
|
76
65
|
end
|
77
66
|
end
|
@@ -1,16 +1,17 @@
|
|
1
1
|
module Billing
|
2
|
-
module
|
2
|
+
module AccountItem
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
included do
|
6
6
|
acts_as_paranoid if respond_to?(:acts_as_paranoid)
|
7
7
|
has_paper_trail class_name: 'Billing::Version' if respond_to?(:has_paper_trail)
|
8
8
|
|
9
|
-
delegate :save, to: :
|
10
|
-
delegate :origins, :payment_types, to: :
|
9
|
+
delegate :save, to: :account, prefix: :account
|
10
|
+
delegate :origins, :payment_types, to: :account
|
11
11
|
|
12
|
-
after_save :
|
13
|
-
|
12
|
+
after_save :account_save
|
13
|
+
|
14
|
+
validates_presence_of :account
|
14
15
|
end
|
15
16
|
|
16
17
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
<%= @account.inspect %>
|
2
|
+
<h2>
|
3
|
+
total: <%= @account.total %>
|
4
|
+
<br />
|
5
|
+
balance: <%= @account.balance %>
|
6
|
+
</h2>
|
7
|
+
<hr />
|
8
|
+
Charges:<br />
|
9
|
+
<% @account.charges.each do |charge| %>
|
10
|
+
<%= charge.inspect %>
|
11
|
+
<% end %>
|
12
|
+
<%= link_to :charge, [:new, @account, :charge] %>
|
13
|
+
<hr />
|
14
|
+
Modifiers:<br />
|
15
|
+
<% @account.modifiers.each do |modifier| %>
|
16
|
+
<%= modifier.inspect %>
|
17
|
+
<% end %>
|
18
|
+
<%= link_to :modifier, [:new, @account, :modifier] %>
|
19
|
+
<div>
|
20
|
+
<% @account.modifier_items.each do |mi| %>
|
21
|
+
<%= mi.inspect %><br />
|
22
|
+
<% end %>
|
23
|
+
</div>
|
24
|
+
<hr />
|
25
|
+
Payments:<br />
|
26
|
+
<% @account.payments.each do |payment| %>
|
27
|
+
<%= payment.inspect %>
|
28
|
+
<% end %>
|
29
|
+
<%= link_to :pay, [:new, @account, :payment] %>
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<h1>
|
2
|
+
New Modifier
|
3
|
+
<small><%= @account %></small>
|
4
|
+
</h1>
|
5
|
+
<div>
|
6
|
+
<%= @modifier.errors.full_messages.join(', ') %>
|
7
|
+
</div>
|
8
|
+
<%= form_for [@account, @modifier] do |f| %>
|
9
|
+
<%= @modifier.inspect %>
|
10
|
+
<br />
|
11
|
+
percent ratio <%= f.number_field :percent_ratio, step: 0.001 %>
|
12
|
+
<br />
|
13
|
+
fixed value <%= f.number_field :fixed_value, step: 0.01 %>
|
14
|
+
<br />
|
15
|
+
<%= f.select :charge_id, @account.charges.collect(&:id), { include_blank: true } %>
|
16
|
+
<br />
|
17
|
+
<%= f.submit %>
|
18
|
+
<% end %>
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Billing</title>
|
5
|
+
<%= stylesheet_link_tag "billing/application", media: "all" %>
|
6
|
+
<%= javascript_include_tag "billing/application" %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
|
11
|
+
<%= yield %>
|
12
|
+
|
13
|
+
</body>
|
14
|
+
</html>
|
data/config/routes.rb
CHANGED
data/lib/billing.rb
CHANGED
data/lib/billing/billable.rb
CHANGED
@@ -9,10 +9,10 @@ module Billing
|
|
9
9
|
module ClassMethods
|
10
10
|
def has_billing(options={})
|
11
11
|
payment_types_scope = options.delete(:payment_types)
|
12
|
-
has_many :
|
13
|
-
provide_billing_items(:
|
12
|
+
has_many :billing_accounts, options.merge(as: :billable).reverse_merge(class_name: 'Billing::Account')
|
13
|
+
provide_billing_items(:billing_accounts)
|
14
14
|
if options[:as]
|
15
|
-
has_many options[:as], options.merge(as: :billable).reverse_merge(class_name: 'Billing::
|
15
|
+
has_many options[:as], options.merge(as: :billable).reverse_merge(class_name: 'Billing::Account')
|
16
16
|
provide_billing_items(options[:as])
|
17
17
|
end
|
18
18
|
if payment_types_scope.present?
|
data/lib/billing/engine.rb
CHANGED
@@ -0,0 +1,32 @@
|
|
1
|
+
module Billing
|
2
|
+
class Mapping
|
3
|
+
attr_reader :name, :i_klass, :i_param, :i_find_key, :i_extra_module
|
4
|
+
def initialize(resource, options)
|
5
|
+
@name = (options[:as] || resource).to_s
|
6
|
+
|
7
|
+
@i_klass = (options[:billable_type] || name.to_s.classify).to_s.constantize
|
8
|
+
|
9
|
+
@i_param = options[:billable_param] || "#{name.singularize}_id" #default #{resource}_id
|
10
|
+
|
11
|
+
# key to find interfaceable in controller, when
|
12
|
+
# :uuid then find_by! :uuid => params[:uuid]
|
13
|
+
# :shop_uuid then find_by! :uuid => params[:shop_uuid]
|
14
|
+
# :shop_id then find_by! :id => params[:shop_id]
|
15
|
+
@i_find_key = @i_param[/^(#{resource}_|)(\w+)/,2]
|
16
|
+
# FIXME not before schema load
|
17
|
+
#raise "#{@i_klass.name} has no method #{@i_find_key}" unless @i_klass.new.respond_to? @i_find_key
|
18
|
+
#raise "Did you forget to add 'has_extface_devices' in #{@i_klass.name} ?" unless @i_klass.new.respond_to? :extface_devices
|
19
|
+
@i_extra_module = options[:controller_include].to_s.constantize if options[:controller_include].present?
|
20
|
+
end
|
21
|
+
|
22
|
+
def mount_point
|
23
|
+
"#{name}_billing"
|
24
|
+
end
|
25
|
+
|
26
|
+
class << self
|
27
|
+
def find(fullpath)
|
28
|
+
Billing.mappings[fullpath[%r{/(\w+)_billing\/}, 1]]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module ActionDispatch::Routing
|
2
|
+
class Mapper
|
3
|
+
def billing_for(resource, options = {})
|
4
|
+
mapping = Billing.add_mapping(resource, options)
|
5
|
+
mount Billing::Engine, at: mapping.mount_point, as: [options[:as],:billing].compact.join('_')
|
6
|
+
get "#{mapping.mount_point}/accounts", to: "billing/accounts#index", as: options[:as] ? options[:as].to_s.pluralize.intern : :billing_accounts
|
7
|
+
get "#{mapping.mount_point}/accounts/:account_id", to: "billing/accounts#show", as: options[:as] ? options[:as].to_s.singularize.intern : :billing_account
|
8
|
+
get "#{mapping.mount_point}/accounts/:account_id/charges", to: "billing/charges#index", as: options[:as] ? "#{options[:as].to_s.singularize.intern}_charges" : :billing_account_charges
|
9
|
+
get "#{mapping.mount_point}/accounts/:account_id/charges/new", to: "billing/charges#new", as: options[:as] ? "#{options[:as].to_s.singularize.intern}_new_charge" : :billing_account_new_charge
|
10
|
+
get "#{mapping.mount_point}/accounts/:account_id/charges/:charge_id", to: "billing/charges#show", as: options[:as] ? "#{options[:as].to_s.singularize.intern}_charge" : :billing_account_charge
|
11
|
+
get "#{mapping.mount_point}/accounts/:account_id/payments", to: "billing/payments#index", as: options[:as] ? "#{options[:as].to_s.singularize.intern}_payments" : :billing_account_payments
|
12
|
+
get "#{mapping.mount_point}/accounts/:account_id/payments/new", to: "billing/payments#new", as: options[:as] ? "#{options[:as].to_s.singularize.intern}_new_payment" : :billing_account_new_payment
|
13
|
+
get "#{mapping.mount_point}/accounts/:account_id/payments/:payment_id", to: "billing/payments#show", as: options[:as] ? "#{options[:as].to_s.singularize.intern}_payment" : :billing_account_payment
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
data/lib/billing/version.rb
CHANGED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
module Billing
|
4
|
+
class AccountsControllerTest < ActionController::TestCase
|
5
|
+
setup do
|
6
|
+
@account = billing_accounts(:one)
|
7
|
+
end
|
8
|
+
|
9
|
+
test "should get index" do
|
10
|
+
get :index
|
11
|
+
assert_response :success
|
12
|
+
end
|
13
|
+
|
14
|
+
test "new" do
|
15
|
+
get :new
|
16
|
+
assert_response :success
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|