kaui 0.14.2 → 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -0
- data/Gemfile +1 -1
- data/README.md +23 -6
- data/app/assets/javascripts/application.js +1 -0
- data/app/assets/stylesheets/application.css +1 -0
- data/app/assets/stylesheets/kaui/header.less +11 -4
- data/app/controllers/kaui/accounts_controller.rb +1 -1
- data/app/controllers/kaui/admin_tenants_controller.rb +113 -18
- data/app/controllers/kaui/bundles_controller.rb +0 -2
- data/app/controllers/kaui/chargebacks_controller.rb +1 -1
- data/app/controllers/kaui/charges_controller.rb +1 -1
- data/app/controllers/kaui/engine_controller.rb +5 -2
- data/app/controllers/kaui/invoices_controller.rb +1 -1
- data/app/controllers/kaui/payment_methods_controller.rb +1 -1
- data/app/controllers/kaui/payments_controller.rb +20 -2
- data/app/controllers/kaui/refunds_controller.rb +1 -1
- data/app/controllers/kaui/subscriptions_controller.rb +8 -13
- data/app/helpers/kaui/account_helper.rb +9 -0
- data/app/helpers/kaui/subscription_helper.rb +47 -21
- data/app/models/kaui/admin_tenant.rb +96 -2
- data/app/models/kaui/bundle.rb +1 -1
- data/app/models/kaui/catalog.rb +138 -0
- data/app/models/kaui/invoice_payment.rb +39 -5
- data/app/models/kaui/overdue.rb +85 -0
- data/app/models/kaui/simple_plan.rb +4 -0
- data/app/models/kaui/transaction.rb +2 -0
- data/app/views/kaui/account_timelines/show.html.erb +2 -1
- data/app/views/kaui/accounts/_billing_info.html.erb +18 -20
- data/app/views/kaui/accounts/_payment_methods.html.erb +11 -16
- data/app/views/kaui/admin_tenants/_form_catalog_translation.erb +24 -0
- data/app/views/kaui/admin_tenants/_form_invoice_template.erb +28 -0
- data/app/views/kaui/admin_tenants/_form_invoice_translation.erb +24 -0
- data/app/views/kaui/admin_tenants/_form_plugin_config.erb +199 -0
- data/app/views/kaui/admin_tenants/_show_catalog.erb +25 -0
- data/app/views/kaui/admin_tenants/_show_catalog_simple.erb +96 -0
- data/app/views/kaui/admin_tenants/_show_catalog_xml.erb +44 -0
- data/app/views/kaui/admin_tenants/_show_overdue.erb +89 -0
- data/app/views/kaui/admin_tenants/new_catalog.html.erb +176 -0
- data/app/views/kaui/admin_tenants/new_overdue_config.html.erb +138 -0
- data/app/views/kaui/admin_tenants/new_plan_currency.html.erb +34 -0
- data/app/views/kaui/admin_tenants/show.html.erb +20 -127
- data/app/views/kaui/bundles/index.html.erb +1 -1
- data/app/views/kaui/invoice_items/_edit_form.html.erb +1 -0
- data/app/views/kaui/layouts/kaui_account_navbar.html.erb +2 -0
- data/app/views/kaui/payments/_payment_table.html.erb +16 -5
- data/app/views/kaui/refunds/_form.html.erb +4 -5
- data/app/views/kaui/subscriptions/_edit_form.html.erb +48 -1
- data/app/views/kaui/subscriptions/_form.html.erb +36 -0
- data/app/views/kaui/subscriptions/_subscriptions_table.html.erb +12 -9
- data/config/routes.rb +8 -0
- data/db/ddl.sql +5 -2
- data/kaui.gemspec +3 -2
- data/lib/kaui/engine.rb +1 -0
- data/lib/kaui/version.rb +1 -1
- data/test/dummy/config/environments/development.rb +1 -1
- data/test/dummy/db/schema.rb +5 -5
- data/test/functional/kaui/account_emails_controller_test.rb +2 -2
- data/test/functional/kaui/accounts_controller_test.rb +4 -4
- data/test/functional/kaui/admin_tenants_controller_test.rb +5 -1
- data/test/functional/kaui/bundle_tags_controller_test.rb +1 -1
- data/test/functional/kaui/bundles_controller_test.rb +4 -4
- data/test/functional/kaui/chargebacks_controller_test.rb +2 -2
- data/test/functional/kaui/charges_controller_test.rb +2 -2
- data/test/functional/kaui/credits_controller_test.rb +2 -2
- data/test/functional/kaui/invoice_items_controller_test.rb +6 -4
- data/test/functional/kaui/invoices_controller_test.rb +2 -2
- data/test/functional/kaui/payments_controller_test.rb +4 -0
- data/test/functional/kaui/refunds_controller_test.rb +2 -2
- data/test/functional/kaui/subscriptions_controller_test.rb +6 -6
- data/test/killbill_test_helper.rb +7 -7
- metadata +47 -8
- data/db/migrate/20130812155313_devise_create_kaui_users.rb +0 -12
- data/db/migrate/20150109214021_create_kaui_tenants.rb +0 -12
- data/db/migrate/20150112232813_create_kaui_allowed_users.rb +0 -19
@@ -7,7 +7,7 @@ class Kaui::AdminTenant < KillBillClient::Model::Tenant
|
|
7
7
|
end
|
8
8
|
|
9
9
|
def upload_overdue_config(overdue_config_xml, user = nil, reason = nil, comment = nil, options = {})
|
10
|
-
KillBillClient::Model::Overdue.
|
10
|
+
KillBillClient::Model::Overdue.upload_tenant_overdue_config_xml(overdue_config_xml, user, reason, comment, options)
|
11
11
|
end
|
12
12
|
|
13
13
|
def upload_invoice_template(invoice_template, is_manual_pay, delete_if_exists, user = nil, reason = nil, comment = nil, options = {})
|
@@ -25,5 +25,99 @@ class Kaui::AdminTenant < KillBillClient::Model::Tenant
|
|
25
25
|
def upload_tenant_plugin_config(plugin_name, plugin_config, user = nil, reason = nil, comment = nil, options = {})
|
26
26
|
KillBillClient::Model::Tenant.upload_tenant_plugin_config(plugin_name, plugin_config, user, reason, comment, options)
|
27
27
|
end
|
28
|
+
|
29
|
+
def get_plugin_repository
|
30
|
+
require 'open-uri'
|
31
|
+
require 'yaml'
|
32
|
+
|
33
|
+
source = URI.parse('https://raw.githubusercontent.com/killbill/killbill-cloud/master/kpm/lib/kpm/plugins_directory.yml').read
|
34
|
+
YAML.load(source)
|
35
|
+
end
|
36
|
+
|
37
|
+
def get_oss_plugin_info(plugin_directory)
|
38
|
+
|
39
|
+
|
40
|
+
# Serialize the plugin state for the view:
|
41
|
+
# plugin_name#plugin_type:prop1,prop2,prop3;plugin_name#plugin_type:prop1,prop2,prop3;...
|
42
|
+
#
|
43
|
+
plugin_config = plugin_directory.inject({}) do |hsh, (k,v)|
|
44
|
+
hsh["#{k}##{v[:type]}"] = v[:require] || []
|
45
|
+
hsh
|
46
|
+
end
|
47
|
+
plugin_config.map { |e,v| "#{e}:#{v.join(",")}" }.join(";")
|
48
|
+
end
|
49
|
+
|
50
|
+
def get_tenant_plugin_config(plugin_directory, options)
|
51
|
+
|
52
|
+
require 'yaml'
|
53
|
+
|
54
|
+
raw_tenant_config = KillBillClient::Model::Tenant::search_tenant_config("PLUGIN_CONFIG_", options)
|
55
|
+
|
56
|
+
tenant_config = raw_tenant_config.inject({}) do |hsh, e|
|
57
|
+
|
58
|
+
# Strip prefix '/PLUGIN_CONFIG_'
|
59
|
+
killbill_key = e.key.gsub!(/PLUGIN_CONFIG_/, '')
|
60
|
+
|
61
|
+
# Extract killbill key for oss plugins based on convention 'killbill-KEY'
|
62
|
+
plugin_key = killbill_key.gsub(/killbill-/, '') if killbill_key.start_with?('killbill-')
|
63
|
+
# If such key exists, lookup in plugin directory
|
64
|
+
plugin_repo_entry = plugin_directory[plugin_key.to_sym] unless plugin_key.nil?
|
65
|
+
# Extract plugin_type based on plugin_directory entry if exists
|
66
|
+
plugin_type = plugin_repo_entry.nil? ? :unknown : plugin_repo_entry[:type].to_sym
|
67
|
+
|
68
|
+
# Deserialize config based on type
|
69
|
+
if plugin_type == :ruby
|
70
|
+
yml = YAML.load(e.values[0])
|
71
|
+
# Hash of properties
|
72
|
+
hsh[plugin_key] = yml[plugin_key.to_sym]
|
73
|
+
elsif plugin_type == :java
|
74
|
+
# Construct hash of properties based on java properties (k1=v1\nk2=v2\n...)
|
75
|
+
hsh[plugin_key] = e.values[0].split("\n").inject({}) do |h, p0|
|
76
|
+
k, v = p0.split('=');
|
77
|
+
h[k] = v;
|
78
|
+
h
|
79
|
+
end
|
80
|
+
else
|
81
|
+
# Construct simple hash with one property :raw_config
|
82
|
+
hsh[killbill_key] = {:raw_config => e.values[0]}
|
83
|
+
end
|
84
|
+
hsh
|
85
|
+
end
|
86
|
+
|
87
|
+
# Serialize the whole thing a as string of the form:
|
88
|
+
# plugin_key1::key1=value1,key2=value2,..;plugin_key2::...
|
89
|
+
tenant_config.map do |plugin_key, props|
|
90
|
+
serialized_props = props.inject("") do |s, (k, v)|
|
91
|
+
e="#{k.to_s}=#{v.to_s}";
|
92
|
+
s == "" ? s="#{e}" : s="#{s},#{e}";
|
93
|
+
s
|
94
|
+
end
|
95
|
+
"#{plugin_key}::#{serialized_props}"
|
96
|
+
end.join(";")
|
97
|
+
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
def format_plugin_config(plugin_name, plugin_type, props)
|
102
|
+
return nil unless props.present?
|
103
|
+
if plugin_type == 'ruby'
|
104
|
+
require 'yaml'
|
105
|
+
hsh = {}
|
106
|
+
hsh[plugin_name.to_sym] = {}
|
107
|
+
props.each do |k,v|
|
108
|
+
hsh[plugin_name.to_sym][k.to_sym] = v.to_sym
|
109
|
+
end
|
110
|
+
hsh[plugin_name.to_sym]
|
111
|
+
hsh.to_yaml
|
112
|
+
elsif plugin_type == 'java'
|
113
|
+
res = ""
|
114
|
+
props.each do |k, v|
|
115
|
+
res = "#{res}#{k.to_s}=#{v.to_s}\n"
|
116
|
+
end
|
117
|
+
res
|
118
|
+
else
|
119
|
+
props['raw_config']
|
120
|
+
end
|
121
|
+
end
|
28
122
|
end
|
29
|
-
end
|
123
|
+
end
|
data/app/models/kaui/bundle.rb
CHANGED
@@ -7,7 +7,7 @@ class Kaui::Bundle < KillBillClient::Model::Bundle
|
|
7
7
|
end
|
8
8
|
|
9
9
|
# Return the active one
|
10
|
-
find_by_external_key(bundle_id_or_key, options)
|
10
|
+
find_by_external_key(bundle_id_or_key, false, options)
|
11
11
|
end
|
12
12
|
|
13
13
|
def self.list_or_search(search_key = nil, offset = 0, limit = 10, options = {})
|
data/app/models/kaui/catalog.rb
CHANGED
@@ -1,2 +1,140 @@
|
|
1
1
|
class Kaui::Catalog < KillBillClient::Model::Catalog
|
2
|
+
|
3
|
+
class << self
|
4
|
+
|
5
|
+
def get_catalog_json(latest, options)
|
6
|
+
|
7
|
+
catalogs = KillBillClient::Model::Catalog.get_tenant_catalog('json', nil, options)
|
8
|
+
return catalogs.length > 0 ? catalogs[catalogs.length - 1] : nil if latest
|
9
|
+
|
10
|
+
# Order by latest
|
11
|
+
result = []
|
12
|
+
catalogs.sort! { |l, r| r.effective_date <=> l.effective_date }
|
13
|
+
|
14
|
+
catalogs.each_with_index do |current_catalog, idx|
|
15
|
+
result << {:version => idx,
|
16
|
+
:version_date => current_catalog.effective_date,
|
17
|
+
:currencies => current_catalog.currencies,
|
18
|
+
:plans => build_existing_simple_plans(current_catalog)}
|
19
|
+
end
|
20
|
+
result
|
21
|
+
end
|
22
|
+
|
23
|
+
def build_ao_mapping(catalog)
|
24
|
+
tmp = {}
|
25
|
+
catalog.products.each do |p|
|
26
|
+
p.available.each do |ap|
|
27
|
+
if !tmp.has_key?(ap)
|
28
|
+
tmp[ap] = []
|
29
|
+
end
|
30
|
+
tmp[ap] << p.name
|
31
|
+
end
|
32
|
+
end unless catalog.nil?
|
33
|
+
tmp.map { |e,v| "#{e}:#{v.join(",")}" }.join(";")
|
34
|
+
end
|
35
|
+
|
36
|
+
|
37
|
+
def get_catalog_xml(options)
|
38
|
+
|
39
|
+
catalog_xml = KillBillClient::Model::Catalog.get_tenant_catalog('xml', nil, options)
|
40
|
+
|
41
|
+
parsed_catalog = parse_catalog_xml(catalog_xml)
|
42
|
+
|
43
|
+
result = []
|
44
|
+
parsed_catalog.keys.each_with_index do |version_date, i|
|
45
|
+
entry = {}
|
46
|
+
entry[:version] = i
|
47
|
+
entry[:version_date] = version_date
|
48
|
+
entry[:xml] = parsed_catalog[version_date]
|
49
|
+
result << entry
|
50
|
+
end
|
51
|
+
result
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def build_existing_simple_plans(catalog)
|
57
|
+
|
58
|
+
tmp = catalog.products.map do |p|
|
59
|
+
p.plans.each do |plan|
|
60
|
+
class << plan
|
61
|
+
attr_accessor :product_name
|
62
|
+
attr_accessor :product_category
|
63
|
+
end
|
64
|
+
plan.product_name = p.name
|
65
|
+
plan.product_category = p.type
|
66
|
+
end
|
67
|
+
end.flatten!
|
68
|
+
|
69
|
+
selected = tmp.select { |p| p.phases.length.to_i <= 2 && p.phases[p.phases.length - 1].type == "EVERGREEN" }
|
70
|
+
|
71
|
+
currencies = catalog.currencies
|
72
|
+
|
73
|
+
result = []
|
74
|
+
selected.each do |plan|
|
75
|
+
has_trial = plan.phases[0].type == 'TRIAL'
|
76
|
+
|
77
|
+
simple_plan = KillBillClient::Model::SimplePlanAttributes.new
|
78
|
+
|
79
|
+
# Embellish SimplePlanAttributes to contain a map currency -> amount (required in the view)
|
80
|
+
class << simple_plan
|
81
|
+
attr_accessor :prices
|
82
|
+
end
|
83
|
+
simple_plan.prices = plan.phases[-1].prices.inject({}) { |r, e| r[e.currency] = e.value; r }
|
84
|
+
|
85
|
+
simple_plan.plan_id = plan.name
|
86
|
+
simple_plan.product_name = plan.product_name
|
87
|
+
simple_plan.product_category = plan.product_category
|
88
|
+
simple_plan.currency = currencies[0]
|
89
|
+
simple_plan.amount = simple_plan.prices[currencies[0]]
|
90
|
+
simple_plan.billing_period = plan.billing_period
|
91
|
+
simple_plan.trial_length = has_trial ? plan.phases[0].duration.number : 0
|
92
|
+
simple_plan.trial_time_unit = has_trial ? plan.phases[0].duration.unit : "N/A"
|
93
|
+
|
94
|
+
result << simple_plan
|
95
|
+
end
|
96
|
+
result
|
97
|
+
end
|
98
|
+
|
99
|
+
def parse_catalog_xml(input_xml)
|
100
|
+
|
101
|
+
require 'nokogiri'
|
102
|
+
|
103
|
+
doc = Nokogiri::XML(input_xml)
|
104
|
+
doc_versions = doc.xpath("//version")
|
105
|
+
|
106
|
+
doc_versions.inject({}) do |hsh, v|
|
107
|
+
|
108
|
+
# Replace node 'version' with 'catalog' and add the attributes
|
109
|
+
v.name = 'catalog'
|
110
|
+
v['xmlns:xsi'] = "http://www.w3.org/2001/XMLSchema-instance"
|
111
|
+
v['xsi:noNamespaceSchemaLocation'] = "CatalogSchema.xsd"
|
112
|
+
# Extract version
|
113
|
+
version = v.search("effectiveDate").text
|
114
|
+
|
115
|
+
# Add entry
|
116
|
+
hsh[version] = '<?xml version="1.0" encoding="utf-8"?>' + format_xml(v.to_s)
|
117
|
+
hsh
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
|
122
|
+
def format_xml(unformatted_xml)
|
123
|
+
|
124
|
+
require "rexml/document"
|
125
|
+
|
126
|
+
# Start by removing all spaces before using rexml
|
127
|
+
unformatted_xml.gsub!(/>\s+</, "><")
|
128
|
+
|
129
|
+
result = ""
|
130
|
+
pdoc = REXML::Document.new(unformatted_xml)
|
131
|
+
formatter = REXML::Formatters::Pretty.new(4)
|
132
|
+
formatter.compact = true
|
133
|
+
formatter.write(pdoc, result)
|
134
|
+
result
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
|
139
|
+
|
2
140
|
end
|
@@ -5,17 +5,51 @@ class Kaui::InvoicePayment < KillBillClient::Model::InvoicePayment
|
|
5
5
|
SAMPLE_REASON_CODES = ['600 - Alt payment method',
|
6
6
|
'699 - OTHER']
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
class << self
|
9
|
+
|
10
|
+
def build_from_raw_payment(raw_payment)
|
11
|
+
|
12
|
+
return nil if raw_payment.nil?
|
13
|
+
|
14
|
+
result = Kaui::InvoicePayment.new
|
15
|
+
KillBillClient::Model::InvoicePaymentAttributes.instance_variable_get('@json_attributes').each do |attr|
|
16
|
+
result.send("#{attr}=", raw_payment.send(attr))
|
17
|
+
end
|
18
|
+
# Use Kaui::Transaction to benefit from additional fields (e.g next_retry_date)
|
19
|
+
original_transactions = (result.transactions || [])
|
20
|
+
result.transactions = []
|
21
|
+
original_transactions.each do |transaction|
|
22
|
+
new_transaction = Kaui::Transaction.new
|
23
|
+
KillBillClient::Model::PaymentTransactionAttributes.instance_variable_get('@json_attributes').each do |attr|
|
24
|
+
new_transaction.send("#{attr}=", transaction.send(attr))
|
25
|
+
end
|
26
|
+
result.transactions << new_transaction
|
27
|
+
end
|
28
|
+
result.build_transactions_next_retry_date!
|
29
|
+
result
|
12
30
|
end
|
13
|
-
|
31
|
+
|
14
32
|
end
|
15
33
|
|
16
34
|
[:auth, :captured, :purchased, :refunded, :credited].each do |type|
|
17
35
|
define_method "#{type}_amount_to_money" do
|
18
36
|
Kaui::Base.to_money(send("#{type}_amount"), currency)
|
19
37
|
end
|
38
|
+
|
39
|
+
|
40
|
+
# For each payment transaction, compute next_retry date by joining with payment attempts
|
41
|
+
def build_transactions_next_retry_date!
|
42
|
+
(transactions || []).each do |transaction|
|
43
|
+
# Filter attempts matching that transaction and SCHEDULED for retry
|
44
|
+
transaction.next_retry_date = (payment_attempts || []).select do |attempt|
|
45
|
+
((attempt.transaction_id && attempt.transaction_id == transaction.transaction_id) ||
|
46
|
+
(attempt.transaction_external_key && attempt.transaction_external_key == transaction.transaction_external_key)) &&
|
47
|
+
attempt.state_name == 'SCHEDULED'
|
48
|
+
end.map do |attempt|
|
49
|
+
attempt.effective_date
|
50
|
+
end.first
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
20
54
|
end
|
21
55
|
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
class Kaui::Overdue < KillBillClient::Model::Overdue
|
2
|
+
|
3
|
+
class << self
|
4
|
+
|
5
|
+
|
6
|
+
def from_overdue_form_model(view_form_model)
|
7
|
+
result = KillBillClient::Model::Overdue.new
|
8
|
+
result.initial_reevaluation_interval = nil # TODO
|
9
|
+
result.overdue_states = []
|
10
|
+
view_form_model["states"].each do |state_model|
|
11
|
+
|
12
|
+
state = KillBillClient::Model::OverdueStateConfig.new
|
13
|
+
state.name = state_model["name"]
|
14
|
+
state.auto_reevaluation_interval_days = nil
|
15
|
+
state.external_message = state_model["external_message"]
|
16
|
+
state.is_clear_state = state_model["is_clear_state"].nil? ? false : state_model["is_clear_state"]
|
17
|
+
state.block_changes = state_model["block_changes"]
|
18
|
+
if state_model["subscription_cancellation_policy"] == :NONE.to_s
|
19
|
+
state.disable_entitlement = false
|
20
|
+
state.subscription_cancellation_policy = nil
|
21
|
+
else
|
22
|
+
state.disable_entitlement = true
|
23
|
+
state.subscription_cancellation_policy = state_model["subscription_cancellation_policy"].blank? ? :NONE : state_model["subscription_cancellation_policy"].to_s.gsub!(/POLICY_/, '')
|
24
|
+
end
|
25
|
+
|
26
|
+
if state_model["condition"]
|
27
|
+
state.condition = KillBillClient::Model::OverdueCondition.new
|
28
|
+
if state_model["condition"]["time_since_earliest_unpaid_invoice_equals_or_exceeds"]
|
29
|
+
state.condition.time_since_earliest_unpaid_invoice_equals_or_exceeds = KillBillClient::Model::DurationAttributes.new
|
30
|
+
state.condition.time_since_earliest_unpaid_invoice_equals_or_exceeds.unit = "DAYS"
|
31
|
+
state.condition.time_since_earliest_unpaid_invoice_equals_or_exceeds.number = state_model["condition"]["time_since_earliest_unpaid_invoice_equals_or_exceeds"]
|
32
|
+
end
|
33
|
+
state.condition.control_tag_inclusion = format_tag_condition(state_model["condition"]["control_tag_inclusion"])
|
34
|
+
state.condition.control_tag_exclusion = format_tag_condition(state_model["condition"]["control_tag_exclusion"])
|
35
|
+
end
|
36
|
+
|
37
|
+
result.overdue_states << state
|
38
|
+
end
|
39
|
+
# We reversed them to display on the form , so we have to reverse them back before uploading new config
|
40
|
+
result.overdue_states.reverse!
|
41
|
+
|
42
|
+
result
|
43
|
+
end
|
44
|
+
|
45
|
+
def get_overdue_json(options)
|
46
|
+
result = KillBillClient::Model::Overdue.get_tenant_overdue_config('json', options)
|
47
|
+
class << result
|
48
|
+
attr_accessor :has_states
|
49
|
+
end
|
50
|
+
result.has_states = result.overdue_states.size > 0 && result.overdue_states[0].is_clear_state
|
51
|
+
|
52
|
+
result.overdue_states.each do |state|
|
53
|
+
class << state
|
54
|
+
attr_accessor :subscription_cancellation
|
55
|
+
end
|
56
|
+
if state.disable_entitlement
|
57
|
+
state.subscription_cancellation = state.subscription_cancellation_policy ? "POLICY_#{state.subscription_cancellation_policy}".to_sym : :NONE
|
58
|
+
else
|
59
|
+
state.subscription_cancellation = :NONE
|
60
|
+
end
|
61
|
+
if state.condition.nil?
|
62
|
+
state.condition = KillBillClient::Model::OverdueCondition.new
|
63
|
+
state.condition.time_since_earliest_unpaid_invoice_equals_or_exceeds = KillBillClient::Model::DurationAttributes.new
|
64
|
+
state.condition.time_since_earliest_unpaid_invoice_equals_or_exceeds.unit = "DAYS"
|
65
|
+
state.condition.time_since_earliest_unpaid_invoice_equals_or_exceeds.number = 0
|
66
|
+
state.condition.control_tag_inclusion = :NONE
|
67
|
+
state.condition.control_tag_exclusion = :NONE
|
68
|
+
end
|
69
|
+
end
|
70
|
+
result
|
71
|
+
end
|
72
|
+
|
73
|
+
def format_tag_condition(control_tag)
|
74
|
+
if control_tag.blank? || control_tag == :NONE.to_s
|
75
|
+
return nil
|
76
|
+
else
|
77
|
+
return control_tag
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
end
|
85
|
+
|
@@ -1,5 +1,7 @@
|
|
1
1
|
class Kaui::Transaction < KillBillClient::Model::Transaction
|
2
2
|
|
3
|
+
attr_accessor :next_retry_date
|
4
|
+
|
3
5
|
def create(account_id = nil, payment_method_id = nil, user = nil, reason = nil, comment = nil, options = {})
|
4
6
|
if transaction_type == 'AUTHORIZE'
|
5
7
|
auth(account_id, payment_method_id, user, reason, comment, options)
|
@@ -204,7 +204,8 @@
|
|
204
204
|
}
|
205
205
|
|
206
206
|
eventsOrder = ["START_ENTITLEMENT", "START_BILLING", "PAUSE_ENTITLEMENT", "PAUSE_BILLING", "RESUME_ENTITLEMENT",
|
207
|
-
"RESUME_BILLING", "PHASE", "CHANGE", "STOP_ENTITLEMENT", "STOP_BILLING", "INVOICE", "
|
207
|
+
"RESUME_BILLING", "PHASE", "CHANGE", "STOP_ENTITLEMENT", "STOP_BILLING", "INVOICE", "AUTHORIZE", "PURCHASE", "CAPTURE",
|
208
|
+
"CREDIT", "REFUND", "VOID", "CHARGEBACK"];
|
208
209
|
|
209
210
|
jQuery.fn.dataTableExt.oSort['timeline-event-asc'] = function(e1,e2) {
|
210
211
|
var x = eventsOrder.indexOf(e1);
|
@@ -8,28 +8,26 @@
|
|
8
8
|
|
9
9
|
<% if can?(:trigger, Kaui::Payment) || can?(:credit, Kaui::Account) || can?(:charge, Kaui::Account) %>
|
10
10
|
<div class="tag-bar tag-bar-breathe">
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
<% end %>
|
11
|
+
<div class="toggler">
|
12
|
+
<div class="toggle">
|
13
|
+
<div class="actions">
|
14
|
+
<!-- Payment, Credit then Charge. Same ordering as in the billing timeline -->
|
15
|
+
<% if can?(:trigger, Kaui::Payment) && @account.account_balance.present? && @account.account_balance > 0 %>
|
16
|
+
<%= link_to '<i class="fa fa-plus-square"></i> Pay all invoices'.html_safe,
|
17
|
+
kaui_engine.pay_all_invoices_account_path(@account.account_id),
|
18
|
+
:method => :post %>
|
19
|
+
<% end %>
|
20
|
+
<% if can? :credit, Kaui::Account %>
|
21
|
+
<%= link_to '<i class="fa fa-plus-square"></i> Add credit'.html_safe,
|
22
|
+
kaui_engine.new_account_credit_path(@account.account_id, :currency => @account.currency) %>
|
23
|
+
<% end %>
|
24
|
+
<% if can? :charge, Kaui::Account %>
|
25
|
+
<%= link_to '<i class="fa fa-plus-square"></i> Create charge'.html_safe,
|
26
|
+
kaui_engine.new_account_charge_path(@account.account_id, :currency => @account.currency) %>
|
27
|
+
<% end %>
|
28
|
+
</div>
|
30
29
|
</div>
|
31
30
|
</div>
|
32
|
-
|
33
31
|
</div>
|
34
32
|
<% end %>
|
35
33
|
|
@@ -2,26 +2,21 @@
|
|
2
2
|
|
3
3
|
<div class="column-block">
|
4
4
|
|
5
|
-
<h1>Payment Methods
|
6
|
-
|
7
|
-
<div class="info-wrapper">
|
8
|
-
|
5
|
+
<h1>Payment Methods
|
9
6
|
<% if can? :create, Kaui::PaymentMethod %>
|
10
|
-
<
|
11
|
-
|
12
|
-
|
13
|
-
<span><i class="fa fa-credit-card"></i><i class="fa fa-caret-down"></i></span>
|
14
|
-
|
15
|
-
<div class="tag-select-box">
|
16
|
-
<%= link_to '<i class="fa fa-plus-square"></i> Add payment method'.html_safe, kaui_engine.new_payment_method_path(:account_id => @account.account_id) %>
|
17
|
-
</div>
|
18
|
-
</div>
|
19
|
-
</div>
|
7
|
+
<%= link_to '<i class="fa fa-plus-square"></i>'.html_safe,
|
8
|
+
kaui_engine.new_payment_method_path(:account_id => @account.account_id),
|
9
|
+
:class => 'btn btn-xs' %>
|
20
10
|
<% end %>
|
11
|
+
</h1>
|
12
|
+
|
13
|
+
<% unless @payment_methods.empty? %>
|
14
|
+
<div class="info-wrapper">
|
21
15
|
|
22
|
-
|
16
|
+
<%= render :partial => 'kaui/payment_methods/payment_methods_table', :locals => {:account => @account, :payment_methods => @payment_methods} %>
|
23
17
|
|
24
|
-
|
18
|
+
</div>
|
19
|
+
<% end %>
|
25
20
|
|
26
21
|
</div>
|
27
22
|
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<% if can? :config_upload, Kaui::AdminTenant %>
|
2
|
+
<div class="tab-pane fade" id="CatalogTranslation">
|
3
|
+
<%= form_tag({:action => :upload_catalog_translation}, :method => 'post', :multipart => true, :class => 'form-horizontal') do %>
|
4
|
+
<%= hidden_field_tag(:id, @tenant.id) %>
|
5
|
+
|
6
|
+
<div class="form-group">
|
7
|
+
<div class="col-sm-10">
|
8
|
+
<%= file_field_tag 'catalog_translation', :class => 'form-control' %>
|
9
|
+
</div>
|
10
|
+
</div>
|
11
|
+
<div class="form-group">
|
12
|
+
<%= label_tag :translation_locale, 'Locale', :class => 'col-sm-2 control-label' %>
|
13
|
+
<div class="col-sm-10">
|
14
|
+
<%= text_field_tag :translation_locale, nil, :class => 'form-control' %>
|
15
|
+
</div>
|
16
|
+
</div>
|
17
|
+
<div class="form-group">
|
18
|
+
<div class="col-sm-10">
|
19
|
+
<%= submit_tag 'Upload', :class => 'btn btn-default' %>
|
20
|
+
</div>
|
21
|
+
</div>
|
22
|
+
<% end %>
|
23
|
+
</div>
|
24
|
+
<% end %>
|
@@ -0,0 +1,28 @@
|
|
1
|
+
<% if can? :config_upload, Kaui::AdminTenant %>
|
2
|
+
<div class="tab-pane fade" id="InvoiceTemplate">
|
3
|
+
<%= form_tag({:action => :upload_invoice_template}, :method => 'post', :multipart => true, :class => 'form-horizontal') do %>
|
4
|
+
<%= hidden_field_tag(:id, @tenant.id) %>
|
5
|
+
|
6
|
+
<div class="form-group">
|
7
|
+
<div class="col-sm-10">
|
8
|
+
<%= file_field_tag 'invoice_template', :class => 'form-control' %>
|
9
|
+
</div>
|
10
|
+
</div>
|
11
|
+
<div class="form-group">
|
12
|
+
<div class="col-sm-10">
|
13
|
+
<div class="checkbox">
|
14
|
+
<label>
|
15
|
+
<%= check_box_tag :manual_pay %>
|
16
|
+
<span>Manual Pay</span>
|
17
|
+
</label>
|
18
|
+
</div>
|
19
|
+
</div>
|
20
|
+
</div>
|
21
|
+
<div class="form-group">
|
22
|
+
<div class="col-sm-offset-2 col-sm-10">
|
23
|
+
<%= submit_tag 'Upload', :class => 'btn btn-default' %>
|
24
|
+
</div>
|
25
|
+
</div>
|
26
|
+
<% end %>
|
27
|
+
</div>
|
28
|
+
<% end %>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
<% if can? :config_upload, Kaui::AdminTenant %>
|
2
|
+
<div class="tab-pane fade" id="InvoiceTranslation">
|
3
|
+
<%= form_tag({:action => :upload_invoice_translation}, :method => 'post', :multipart => true, :class => 'form-horizontal') do %>
|
4
|
+
<%= hidden_field_tag(:id, @tenant.id) %>
|
5
|
+
|
6
|
+
<div class="form-group">
|
7
|
+
<div class="col-sm-10">
|
8
|
+
<%= file_field_tag 'invoice_translation', :class => 'form-control' %>
|
9
|
+
</div>
|
10
|
+
</div>
|
11
|
+
<div class="form-group">
|
12
|
+
<%= label_tag :translation_locale, 'Locale', :class => 'col-sm-2 control-label' %>
|
13
|
+
<div class="col-sm-10">
|
14
|
+
<%= text_field_tag :translation_locale, nil, :class => 'form-control' %>
|
15
|
+
</div>
|
16
|
+
</div>
|
17
|
+
<div class="form-group">
|
18
|
+
<div class="col-sm-10">
|
19
|
+
<%= submit_tag 'Upload', :class => 'btn btn-default' %>
|
20
|
+
</div>
|
21
|
+
</div>
|
22
|
+
<% end %>
|
23
|
+
</div>
|
24
|
+
<% end %>
|