kaui 0.14.2 → 0.15.0
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.
- 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 %>
|