kaui 0.14.2 → 0.15.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +2 -0
  3. data/Gemfile +1 -1
  4. data/README.md +23 -6
  5. data/app/assets/javascripts/application.js +1 -0
  6. data/app/assets/stylesheets/application.css +1 -0
  7. data/app/assets/stylesheets/kaui/header.less +11 -4
  8. data/app/controllers/kaui/accounts_controller.rb +1 -1
  9. data/app/controllers/kaui/admin_tenants_controller.rb +113 -18
  10. data/app/controllers/kaui/bundles_controller.rb +0 -2
  11. data/app/controllers/kaui/chargebacks_controller.rb +1 -1
  12. data/app/controllers/kaui/charges_controller.rb +1 -1
  13. data/app/controllers/kaui/engine_controller.rb +5 -2
  14. data/app/controllers/kaui/invoices_controller.rb +1 -1
  15. data/app/controllers/kaui/payment_methods_controller.rb +1 -1
  16. data/app/controllers/kaui/payments_controller.rb +20 -2
  17. data/app/controllers/kaui/refunds_controller.rb +1 -1
  18. data/app/controllers/kaui/subscriptions_controller.rb +8 -13
  19. data/app/helpers/kaui/account_helper.rb +9 -0
  20. data/app/helpers/kaui/subscription_helper.rb +47 -21
  21. data/app/models/kaui/admin_tenant.rb +96 -2
  22. data/app/models/kaui/bundle.rb +1 -1
  23. data/app/models/kaui/catalog.rb +138 -0
  24. data/app/models/kaui/invoice_payment.rb +39 -5
  25. data/app/models/kaui/overdue.rb +85 -0
  26. data/app/models/kaui/simple_plan.rb +4 -0
  27. data/app/models/kaui/transaction.rb +2 -0
  28. data/app/views/kaui/account_timelines/show.html.erb +2 -1
  29. data/app/views/kaui/accounts/_billing_info.html.erb +18 -20
  30. data/app/views/kaui/accounts/_payment_methods.html.erb +11 -16
  31. data/app/views/kaui/admin_tenants/_form_catalog_translation.erb +24 -0
  32. data/app/views/kaui/admin_tenants/_form_invoice_template.erb +28 -0
  33. data/app/views/kaui/admin_tenants/_form_invoice_translation.erb +24 -0
  34. data/app/views/kaui/admin_tenants/_form_plugin_config.erb +199 -0
  35. data/app/views/kaui/admin_tenants/_show_catalog.erb +25 -0
  36. data/app/views/kaui/admin_tenants/_show_catalog_simple.erb +96 -0
  37. data/app/views/kaui/admin_tenants/_show_catalog_xml.erb +44 -0
  38. data/app/views/kaui/admin_tenants/_show_overdue.erb +89 -0
  39. data/app/views/kaui/admin_tenants/new_catalog.html.erb +176 -0
  40. data/app/views/kaui/admin_tenants/new_overdue_config.html.erb +138 -0
  41. data/app/views/kaui/admin_tenants/new_plan_currency.html.erb +34 -0
  42. data/app/views/kaui/admin_tenants/show.html.erb +20 -127
  43. data/app/views/kaui/bundles/index.html.erb +1 -1
  44. data/app/views/kaui/invoice_items/_edit_form.html.erb +1 -0
  45. data/app/views/kaui/layouts/kaui_account_navbar.html.erb +2 -0
  46. data/app/views/kaui/payments/_payment_table.html.erb +16 -5
  47. data/app/views/kaui/refunds/_form.html.erb +4 -5
  48. data/app/views/kaui/subscriptions/_edit_form.html.erb +48 -1
  49. data/app/views/kaui/subscriptions/_form.html.erb +36 -0
  50. data/app/views/kaui/subscriptions/_subscriptions_table.html.erb +12 -9
  51. data/config/routes.rb +8 -0
  52. data/db/ddl.sql +5 -2
  53. data/kaui.gemspec +3 -2
  54. data/lib/kaui/engine.rb +1 -0
  55. data/lib/kaui/version.rb +1 -1
  56. data/test/dummy/config/environments/development.rb +1 -1
  57. data/test/dummy/db/schema.rb +5 -5
  58. data/test/functional/kaui/account_emails_controller_test.rb +2 -2
  59. data/test/functional/kaui/accounts_controller_test.rb +4 -4
  60. data/test/functional/kaui/admin_tenants_controller_test.rb +5 -1
  61. data/test/functional/kaui/bundle_tags_controller_test.rb +1 -1
  62. data/test/functional/kaui/bundles_controller_test.rb +4 -4
  63. data/test/functional/kaui/chargebacks_controller_test.rb +2 -2
  64. data/test/functional/kaui/charges_controller_test.rb +2 -2
  65. data/test/functional/kaui/credits_controller_test.rb +2 -2
  66. data/test/functional/kaui/invoice_items_controller_test.rb +6 -4
  67. data/test/functional/kaui/invoices_controller_test.rb +2 -2
  68. data/test/functional/kaui/payments_controller_test.rb +4 -0
  69. data/test/functional/kaui/refunds_controller_test.rb +2 -2
  70. data/test/functional/kaui/subscriptions_controller_test.rb +6 -6
  71. data/test/killbill_test_helper.rb +7 -7
  72. metadata +47 -8
  73. data/db/migrate/20130812155313_devise_create_kaui_users.rb +0 -12
  74. data/db/migrate/20150109214021_create_kaui_tenants.rb +0 -12
  75. data/db/migrate/20150112232813_create_kaui_allowed_users.rb +0 -19
@@ -0,0 +1,199 @@
1
+ <% if can? :config_upload, Kaui::AdminTenant %>
2
+ <div class="tab-pane fade" id="PluginConfig">
3
+
4
+ </br>
5
+ <div>
6
+ <h1>Upload Plugin Configuration
7
+ </h1>
8
+ </div>
9
+
10
+ <%= form_tag({:action => :upload_plugin_config}, :method => 'post', :multipart => true, :class => 'form-horizontal') do %>
11
+ <%= hidden_field_tag(:id, @tenant.id) %>
12
+
13
+ <div class="form-group">
14
+ <%= label_tag :plugin_name, 'Plugin name', :class => 'col-sm-2 control-label' %>
15
+ <div class="col-sm-4">
16
+ <%= text_field_tag :plugin_name, nil, :class => 'form-control', :plugin_config => @plugin_config, :tenant_plugin_config => @tenant_plugin_config %>
17
+ </div>
18
+ </div>
19
+ <!-- Anchor DIV that gets thrown away when switching plugins -->
20
+ <div id="plugin_config_properties" , plugin_name="" , class="col-sm-10">
21
+ </div>
22
+ <div class="form-group">
23
+ <div class="col-sm-offset-2 col-sm-10">
24
+ <%= submit_tag 'Upload', :class => 'btn btn-default' %>
25
+ </div>
26
+ </div>
27
+ <% end %>
28
+ </div>
29
+ <% end %>
30
+
31
+ <%= javascript_tag do %>
32
+
33
+ function get_existing_tenant_plugin_properties(plugin_name) {
34
+
35
+ var tenant_plugin_properties = $('#plugin_name').attr('tenant_plugin_config');
36
+ var res = {}
37
+ if (tenant_plugin_properties != undefined) {
38
+ $.each(tenant_plugin_properties.split(';'), function(idx, el) {
39
+ var el_parts = el.split('::');
40
+ var el_plugin_name = el_parts[0];
41
+ var el_props = el_parts[1];
42
+ if (el_plugin_name == plugin_name) {
43
+ if (el_props.split('=')[0] == 'raw_config') {
44
+ res['raw_config'] = el_props.substr(11);
45
+ } else {
46
+ $.map(el_props.split(','), function(el) {
47
+ var parts = el.split('=');
48
+ res[parts[0]] = parts[1];
49
+ });
50
+ }
51
+ return false;
52
+ }
53
+ });
54
+ }
55
+ return res;
56
+ }
57
+
58
+ function get_selected_plugin_info() {
59
+ var plugin_name = $('#plugin_name').val();
60
+ var plugin_config_str = $('#plugin_name').attr('plugin_config');
61
+
62
+ var res = {}
63
+ /* Deserialize plugin/properties (see AdminTenant model)*/
64
+ $.each(plugin_config_str.split(';'), function(idx, el) {
65
+ var el_parts = el.split(':');
66
+ var el_parts_key = el_parts[0].split('#');
67
+ var el_plugin_name = el_parts_key[0];
68
+ var el_plugin_type = el_parts_key[1];
69
+ var el_plugin_props = el_parts[1];
70
+ if (el_plugin_name == plugin_name) {
71
+ res['type'] = el_plugin_type;
72
+ res['props'] = el_plugin_props == "" ? [] : (el_plugin_type == "" ? ['raw_config'] : el_plugin_props.split(','));
73
+ return false;
74
+ }
75
+ });
76
+
77
+ if (res['props'] == undefined) {
78
+ res['type'] = '';
79
+ res['props'] = ['raw_config'];
80
+ }
81
+
82
+ return res;
83
+ }
84
+
85
+ function init_plugin_config_source() {
86
+ var plugin_config_str = $('#plugin_name').attr('plugin_config');
87
+ var res = []
88
+ $.map(plugin_config_str.split(";"), function(el) { res.push(el.split(':')[0].split('#')[0]) });
89
+ return res;
90
+ }
91
+
92
+ function add_properties_for_plugin(plugin_name, plugin_info) {
93
+
94
+ if (plugin_name == "") {
95
+ $('#plugin_config_properties').empty();
96
+ return;
97
+ }
98
+
99
+ if ($('#plugin_config_properties').attr('plugin_name') == plugin_name) {
100
+ /* Already set...*/
101
+ return;
102
+ }
103
+
104
+ var type = plugin_info['type'];
105
+ var props = plugin_info['props']
106
+
107
+ /* Prune the tree to restart from scratch */
108
+ $('#plugin_config_properties').empty();
109
+
110
+ $('#plugin_config_properties').append('<input type="hidden" name="plugin_type" id="plugin_type" value="' + type + '" />');
111
+ $('#plugin_config_properties').append('<label class="col-sm-2 control-label" for="plugin_name">Plugin Properties</label>');
112
+ $('#plugin_config_properties').append('<div id="plugin_config_properties_anchor" class="col-sm-offset-2 col-sm-10">');
113
+
114
+ /* Retrieve existing plugin properties for this tenant */
115
+ var existing_props = get_existing_tenant_plugin_properties(plugin_name);
116
+
117
+ var merged_props_with_values = existing_props;
118
+ if (props != undefined) {
119
+ $.each(props, function(idx, p) {
120
+ if (merged_props_with_values[p] == undefined) {
121
+ merged_props_with_values[p] = '';
122
+ }
123
+ });
124
+ }
125
+
126
+ $.each(merged_props_with_values, function(p, v) {
127
+ add_property_form_entry(format_label(p), p, v);
128
+ });
129
+
130
+ $('#plugin_config_properties').attr('plugin_name', plugin_name);
131
+ }
132
+
133
+ function format_label(input) {
134
+ /* Keep latest piece of a system property to keep it short */
135
+ var label_name = input.split('.').pop();
136
+ /* Replace underscore with comma */
137
+ label_name = label_name.replace(/_/g, ',');
138
+ /* Replace uppercase with comma + uppercase */
139
+ label_name = label_name.replace(/([A-Z]+)/g, ",$1");
140
+ /* Split name make sure each word starts with Uppercase */
141
+ var tmp1 = label_name.split(',');
142
+ var label_name_array = [];
143
+ $.map(tmp1, function(el) { label_name_array.push(el.charAt(0).toUpperCase() + el.slice(1)) });
144
+ label_name = label_name_array.join(' ');
145
+ return label_name;
146
+ }
147
+
148
+ function add_property_form_entry(property_label, property, current_value) {
149
+
150
+ var clone = $('#PluginConfig form div').first().clone();
151
+ clone.children("label").attr('for', property).text(property_label);
152
+ clone.children("div").first().attr("name", property).attr("id", property);
153
+ var input = clone.children("div").children("input").first();
154
+ input.removeAttr('autocomplete').removeAttr('plugin_config');
155
+ if (property == 'raw_config') {
156
+ var text_area = $('<textarea name="plugin_properties[raw_config]" id="raw_config" rows="10" class="form-control">');
157
+ input.replaceWith(text_area);
158
+ text_area.attr("name", "plugin_properties[" + property + "]")
159
+ .attr("id", property)
160
+ .attr('class', 'form-control')
161
+ .val(current_value);
162
+
163
+ input.replaceWith('<textarea name="plugin_properties[raw_config]" id="raw_config" rows="10" class="form-control">').text(current_value);
164
+ } else {
165
+ input.attr("name", "plugin_properties[" + property + "]")
166
+ .attr("id", property)
167
+ .attr('class', 'form-control')
168
+ .val(current_value);
169
+ }
170
+
171
+ /* Attach clone object */
172
+ $('#plugin_config_properties_anchor').append(clone);
173
+
174
+ }
175
+
176
+
177
+ function init_plugin_name_handlers() {
178
+ /* Intercept ENTER and potentially display property form if plugin is know */
179
+ $('#plugin_name').keyup(function (e) {
180
+ if (e.keyCode === 13) {
181
+ add_properties_for_plugin($('#plugin_name').val(), get_selected_plugin_info());
182
+ }
183
+ });
184
+
185
+ /* Intercept mouseleave and potentially display property form if plugin is know */
186
+ $('#plugin_name').on('mouseleave', function() {
187
+ add_properties_for_plugin($('#plugin_name').val(), get_selected_plugin_info());
188
+ });
189
+
190
+ /* Attach auto-completion source */
191
+ $('#plugin_name').autocomplete({
192
+ source: init_plugin_config_source()
193
+ });
194
+ }
195
+
196
+ $(document).ready(function() {
197
+ init_plugin_name_handlers();
198
+ });
199
+ <% end %>
@@ -0,0 +1,25 @@
1
+ <div class="tab-pane fade in active" id="CatalogShow">
2
+ <%= render :partial => 'show_catalog_simple' %>
3
+ <%= render :partial => 'show_catalog_xml' %>
4
+ </div>
5
+
6
+
7
+ <%= javascript_tag do %>
8
+
9
+ function switchBasicConfig() {
10
+ $('#catalog_xml').hide();
11
+ initBasicConfig();
12
+ $('#catalog_simple').show();
13
+ }
14
+
15
+ function switchXMLConfig() {
16
+ $('#catalog_simple').hide();
17
+ $('#catalog_xml').show();
18
+ }
19
+
20
+ $(document).ready(function() {
21
+ switchBasicConfig();
22
+ });
23
+
24
+ <% end %>
25
+
@@ -0,0 +1,96 @@
1
+ <div id="catalog_simple">
2
+ <hr/>
3
+
4
+ <h1>Existing Plans
5
+ <% if can? :config_upload, Kaui::AdminTenant %>
6
+ <%= link_to '<i class="fa fa-plus-square"></i>'.html_safe,
7
+ kaui_engine.admin_tenant_new_catalog_path(:id => @tenant.id),
8
+ :class => 'btn btn-xs' %>
9
+ <% end %>
10
+ <a class='btn btn-xs' href="javascript:void(0);" onclick="switchXMLConfig();">Enable XML View</a>
11
+ </h1>
12
+
13
+ <table id="existing-plans-for-tenants" class="table table-condensed">
14
+
15
+ <span class='label'>
16
+ <b>Catalog Versions:</b>
17
+ </span>
18
+ <select id="select_catalog" class="selectpicker show-menu-arrow">
19
+ <% @catalogs.each_with_index do |catalog, i| %>
20
+ <option idx="<%= catalog[:version] %>"><%= format_date(catalog[:version_date]) %></option>
21
+ <% end %>
22
+ </select>
23
+
24
+ <thead>
25
+ <tr>
26
+ <th>Plan Id</th>
27
+ <th>Product</th>
28
+ <th>Category</th>
29
+ <th>Billing Period</th>
30
+ <% @catalogs.each do |catalog| %>
31
+ <th class="catalog_version_<%= catalog[:version] %>">
32
+ <select id="select_currencies_<%= catalog[:version] %>" class="selectpicker show-menu-arrow">
33
+ <% catalog[:currencies].each_with_index do |currency, i| %>
34
+ <option><%= currency %></option>
35
+ <% end %>
36
+ </select>
37
+ </th>
38
+ <% end %>
39
+ <th>Trial</th>
40
+ <th></th>
41
+ </tr>
42
+ </thead>
43
+ <tbody>
44
+ <% @catalogs.each do |catalog| %>
45
+ <% catalog[:plans].each do |p| %>
46
+ <tr class="catalog_version_<%= catalog[:version] %>">
47
+ <td><%= p.plan_id %></td>
48
+ <td><%= humanized_product_name(p.product_name) %></td>
49
+ <td><%= humanized_product_category(p.product_category) %></td>
50
+ <td><%= humanized_billing_period(p.billing_period) %></td>
51
+ <td>
52
+ <% catalog[:currencies].each do |c| %>
53
+ <span class="plan_currency_<%= c %>"><%= p.prices[c] %></span>
54
+ <% end %>
55
+ </td>
56
+ <td><%= p.trial_length != 0 ? "#{p.trial_length} #{humanized_time_unit(p.trial_time_unit)}" : "N/A" %></td>
57
+ <td><%= link_to '<i class="fa fa-plus-square"></i>'.html_safe + " currency", kaui_engine.admin_tenant_new_plan_currency_path(:id => @tenant.id, :plan_id => p.plan_id),
58
+ :class => 'btn btn-xs' %></td>
59
+ </tr>
60
+ <% end %>
61
+ <% end %>
62
+ </tbody>
63
+ </table>
64
+ </div>
65
+
66
+
67
+ <%= javascript_tag do %>
68
+
69
+ function initBasicConfig() {
70
+ displayCatalogVersion();
71
+ displayAmountsForCurrency();
72
+ }
73
+
74
+ function displayCatalogVersion() {
75
+ $('[class^="catalog_version_"]').hide();
76
+ $("[class^=catalog_version_" + $("#select_catalog option:selected" ).attr("idx") + "]").show();
77
+ }
78
+
79
+ function displayAmountsForCurrency() {
80
+ var catalogVersion = $("#select_catalog option:selected" ).attr("idx");
81
+ $('[class^="plan_currency_"]').hide();
82
+ $("[class^=plan_currency_" + $("#select_currencies_" + catalogVersion + " option:selected" ).text() + "]").show();
83
+ }
84
+
85
+ $(document).ready(function() {
86
+
87
+ $("#select_catalog").change(function() {
88
+ displayCatalogVersion();
89
+ });
90
+
91
+ $('[id^="select_currencies"]').change(function() {
92
+ displayAmountsForCurrency();
93
+ });
94
+ });
95
+ <% end %>
96
+
@@ -0,0 +1,44 @@
1
+ <div id="catalog_xml">
2
+ <hr/>
3
+
4
+ <div>
5
+ <h1>Catalog XML
6
+ <a class="btn btn btn-xs" href="javascript:void(0);" onclick="switchBasicConfig();">Enable Simple Configuration</a>
7
+ </h1>
8
+
9
+
10
+ <table id="catalog-xml-for-tenant" class="table table-condensed">
11
+
12
+ <thead>
13
+ <tr>
14
+ <th>Catalog Version</th>
15
+ <th>Effective Date</th>
16
+ <th>Catalog XML</th>
17
+ </tr>
18
+ </thead>
19
+ <tbody>
20
+ <% @catalogs_xml.each do |catalog| %>
21
+ <tr>
22
+ <td><%= catalog[:version] %></td>
23
+ <td><%= format_date(catalog[:version_date]) %></td>
24
+ <td>
25
+ <%= form_tag(kaui_engine.admin_tenant_display_catalog_xml_path, :id => "submit_form_xml_#{catalog[:version]}", :method => 'post', :multipart => true, :class => "hide") do %>
26
+ <%= hidden_field_tag(:xml, catalog[:xml]) %>
27
+ <%= submit_tag 'submit' %>
28
+ <% end %>
29
+ <a class='btn btn-xs' href="javascript:void(0);" onclick="submit_xml(<%= catalog[:version] %>);">view xml</a>
30
+ </td>
31
+ </tr>
32
+ <% end %>
33
+ </tbody>
34
+ </table>
35
+
36
+ </div>
37
+ </div>
38
+
39
+ <%= javascript_tag do %>
40
+ function submit_xml(version_id) {
41
+ $("#submit_form_xml_" + version_id).submit();
42
+ };
43
+ <% end %>
44
+
@@ -0,0 +1,89 @@
1
+ <div class="tab-pane fade" id="OverdueShow">
2
+
3
+
4
+ <hr/>
5
+
6
+ <h1>Existing Overdue Config
7
+ <% if can? :config_upload, Kaui::AdminTenant %>
8
+ <%= link_to '<i class="fa fa-plus-square"></i>'.html_safe,
9
+ kaui_engine.admin_tenant_new_overdue_config_path(:id => @tenant.id),
10
+ :class => 'btn btn-xs' %>
11
+ <% end %>
12
+ <a class='btn btn-xs' href="javascript:void(0);" onclick="submit_overdue_xml();">View overdue xml</a>
13
+ </h1>
14
+
15
+ <table id="existing-overdue-config-for-tenants" class="table table-condensed">
16
+
17
+ <span class='label'>
18
+ </span>
19
+ <% if @overdue.nil? || @overdue.has_states %>
20
+ No overdue configuration defined for tenant
21
+ <% else %>
22
+ <thead>
23
+ <tr>
24
+ <th>Name</th>
25
+ <th>External Message</th>
26
+ <th>Actions</th>
27
+ <th>Conditions</th>
28
+ </tr>
29
+ </thead>
30
+ <tbody>
31
+ <% @overdue.overdue_states.reverse_each do |state| %>
32
+ <tr class="overdue_state_<%= state %>">
33
+ <td><%= state.name %></td>
34
+ <td><%= state.external_message %></td>
35
+ <td>
36
+ <ul>
37
+ <% if state.block_changes %>
38
+ <li>
39
+ <%= 'Block changes:' %><%= state.block_changes %>
40
+ </li>
41
+ <% end %>
42
+ <% if state.disable_entitlement %>
43
+ <li>
44
+ <%= 'Cancel subscriptions:' %><%= state.disable_entitlement %>
45
+ (policy:<%= state.subscription_cancellation_policy %>)
46
+ </li>
47
+ <% end %>
48
+ </ul>
49
+ </td>
50
+ <td>
51
+ <% if state.condition %>
52
+ <ul>
53
+ <% if state.condition.time_since_earliest_unpaid_invoice_equals_or_exceeds %>
54
+ <li>
55
+ <%= 'Time Since earliest unpaid invoice >=' %> <%= state.condition.time_since_earliest_unpaid_invoice_equals_or_exceeds.number %><%= state.condition.time_since_earliest_unpaid_invoice_equals_or_exceeds.unit %>
56
+ </li>
57
+ <% end %>
58
+ <% if state.condition.control_tag_inclusion %>
59
+ <li>
60
+ <%= 'Control tag inclusion' %> <%= state.condition.control_tag_inclusion %>
61
+ </li>
62
+ <% end %>
63
+ <% if state.condition.control_tag_exclusion %>
64
+ <li>
65
+ <%= 'Control tag exclusion' %> <%= state.condition.control_tag_exclusion %>
66
+ </li>
67
+ <% end %>
68
+ </ul>
69
+ <% end %>
70
+ </td>
71
+ </tr>
72
+ <% end %>
73
+ <% end %>
74
+ </tbody>
75
+ </table>
76
+
77
+ <%= form_tag(kaui_engine.admin_tenant_display_overdue_xml_path, :id => "submit_overdue_form_xml", :method => 'post', :multipart => true, :class => "hide") do %>
78
+ <%= hidden_field_tag(:xml, @overdue_xml) %>
79
+ <%= submit_tag 'submit' %>
80
+ <% end %>
81
+
82
+ </div>
83
+
84
+
85
+ <%= javascript_tag do %>
86
+ function submit_overdue_xml() {
87
+ $("#submit_overdue_form_xml").submit();
88
+ };
89
+ <% end %>
@@ -0,0 +1,176 @@
1
+ <div id="catalog_simple">
2
+
3
+ <div>
4
+ <h1>Catalog Configuration
5
+ <a class='btn btn-xs' href="javascript:void(0);" onclick="switch_xml_config();">Enable Advanced Configuration (Upload XML)</a>
6
+ </h1>
7
+ </div>
8
+ <%= form_for @simple_plan, :url => {:action => :create_simple_plan}, :html => {:class => 'form-horizontal'} do |f| %>
9
+
10
+ <%= f.hidden_field_tag(:id, @tenant.id) %>
11
+ <div class="form-group" id="form_category">
12
+ <%= f.label :product_category, 'Product Category', :class => 'col-sm-3 control-label' %>
13
+ <div class="col-sm-4">
14
+ <%= f.select :product_category, options_for_select(@product_categories.map {|p| [humanized_product_category(p), p] }, :Base), :class => 'form-control' %>
15
+ </div>
16
+ </div>
17
+ <div class="form-group">
18
+ <%= f.label :product_name, 'Product Name', :class => 'col-sm-3 control-label' %>
19
+ <div class="col-sm-4">
20
+ <%= f.text_field :product_name, :class => 'form-control', :known_base => @available_base_products.join(","), :known_ao => @available_ao_products.join(","), :known_std => @available_standalone_products.join(","), :ao_mappings => @ao_mapping %>
21
+ </div>
22
+ </div>
23
+ <div class="form-group">
24
+ <%= f.label :plan_id, 'Plan Name', :class => 'col-sm-3 control-label' %>
25
+ <div class="col-sm-4">
26
+ <%= f.text_field :plan_id, :class => 'form-control' %>
27
+ </div>
28
+ </div>
29
+ <div class="form-group" id="form_base_products">
30
+ <%= f.label :available_base_products, 'Available Base Products', :class => 'col-sm-3 control-label' %>
31
+ <div class="col-sm-4">
32
+ <%= f.select :available_base_products, options_for_select(@available_base_products), {}, {:multiple => true, :class => "form-control"} %>
33
+ </div>
34
+ </div>
35
+ <div class="form-group">
36
+ <%= f.label :amount, 'Amount', :class => 'col-sm-3 control-label' %>
37
+ <div class="col-sm-4">
38
+ <%= f.text_field :amount, :class => 'form-control' %>
39
+ </div>
40
+ </div>
41
+ <div class="form-group">
42
+ <%= f.label :currency, 'Currency', :class => 'col-sm-3 control-label' %>
43
+ <div class="col-sm-4">
44
+ <%= f.select :currency, currencies, {:selected => 'USD'}, :class => 'form-control' %>
45
+ </div>
46
+ </div>
47
+ <div class="form-group">
48
+ <%= f.label :billing_period, 'Billing Period', :class => 'col-sm-3 control-label' %>
49
+ <div class="col-sm-4">
50
+ <%= f.select :billing_period, options_for_select(@billing_period.map {|bp| [humanized_billing_period(bp), bp] }, :MONTHLY), :class => 'form-control' %>
51
+ </div>
52
+ </div>
53
+ <div class="form-group">
54
+ <%= f.label :trial_length, 'Trial Length', :class => 'col-sm-3 control-label' %>
55
+ <div class="col-sm-4">
56
+ <%= f.text_field :trial_length, :value => 0, :class => 'form-control' %>
57
+ </div>
58
+ </div>
59
+ <div class="form-group">
60
+ <%= f.label :trial_time_unit, 'Trial Time Unit', :class => 'col-sm-3 control-label' %>
61
+ <div class="col-sm-4">
62
+ <%= f.select :trial_time_unit, options_for_select(@time_units.map {|tu| [humanized_time_unit(tu), tu]}, :UNLIMITED), :class => 'form-control' %>
63
+ </div>
64
+ </div>
65
+ <div class="form-group">
66
+ <div class="col-sm-offset-3 col-sm-9">
67
+ <%= submit_tag 'Save', :class => 'btn btn-default' %>
68
+ </div>
69
+ </div>
70
+ <% end %>
71
+ </div>
72
+
73
+
74
+ <div id="catalog_xml">
75
+ <div>
76
+ <h1>Advanced Configuration
77
+ <a class="btn btn btn-xs" href="javascript:void(0);" onclick="switch_basic_config();">Enable Simple Configuration</a>
78
+ </h1>
79
+ </div>
80
+
81
+
82
+ <%= form_tag({:action => :upload_catalog}, :method => 'post', :multipart => true, :class => 'form-horizontal') do %>
83
+ <%= hidden_field_tag(:id, @tenant.id) %>
84
+
85
+ <div class="form-group">
86
+ <div class="col-sm-10">
87
+ <%= file_field_tag 'catalog', :class => 'form-control' %>
88
+ </div>
89
+ </div>
90
+ <div class="form-group">
91
+ <div class="col-sm-10">
92
+ <%= submit_tag 'Upload', :class => 'btn btn-default' %>
93
+ </div>
94
+ </div>
95
+ <% end %>
96
+ </div>
97
+
98
+
99
+ <%= javascript_tag do %>
100
+
101
+ function known_products() {
102
+ var result = [];
103
+ var selected_category = $("#simple_plan_product_category option:selected" ).text();
104
+ if (selected_category == 'Base') {
105
+ result = $('#simple_plan_product_name').attr('known_base');
106
+ } else if (selected_category == 'Add_on') {
107
+ result = $('#simple_plan_product_name').attr('known_ao');
108
+ } else {
109
+ result = $('#simple_plan_product_name').attr('known_std');
110
+ }
111
+ return result.split(",");
112
+ }
113
+
114
+ function switch_xml_config() {
115
+ $('#catalog_simple').hide();
116
+ $('#catalog_xml').show();
117
+ }
118
+
119
+ function recompute_available_base_products_for_ao() {
120
+ if ($("#simple_plan_product_category option:selected" ).text() != 'Add_on') {
121
+ return;
122
+ }
123
+ var product_name = $('#simple_plan_product_name').val();
124
+
125
+ var ao_mappings_str = $('#simple_plan_product_name').attr('ao_mappings');
126
+ if (ao_mappings_str != "") {
127
+ var ao_mappings = {};
128
+ $.map(ao_mappings_str.split(";"), function(el) { sel = el.split(':'); ao_mappings[sel[0]] = sel[1].split(',') });
129
+ if (ao_mappings[product_name] != undefined) {
130
+ $('#simple_plan_available_base_products').val(ao_mappings[product_name]);
131
+ return;
132
+ }
133
+ }
134
+ /* Unless we found a mapping to update, we clear the existing mapping */
135
+ $('#simple_plan_available_base_products').val([]);
136
+ }
137
+
138
+ function display_available_base_products_for_ao() {
139
+ /* Reset prodcut name value; known_products from auto completion will also be updated accordingly */
140
+ $('#simple_plan_product_name').val('');
141
+
142
+ if ($("#simple_plan_product_category option:selected" ).text() == 'Add_on') {
143
+ $('#form_base_products').show();
144
+ } else {
145
+ $('#form_base_products').hide();
146
+ }
147
+ }
148
+
149
+ function switch_basic_config() {
150
+ $('#catalog_xml').hide();
151
+ $('#catalog_simple').show();
152
+ }
153
+
154
+
155
+ $(document).ready(function() {
156
+ switch_basic_config();
157
+
158
+ $('#simple_plan_product_name').autocomplete({
159
+ source: function(query, process) {
160
+ process(known_products());
161
+ }
162
+ });
163
+
164
+ $('#simple_plan_product_category').change(function() {
165
+ display_available_base_products_for_ao();
166
+ });
167
+ display_available_base_products_for_ao();
168
+
169
+
170
+ $('#simple_plan_product_name').on('mouseleave', function() {
171
+ recompute_available_base_products_for_ao();
172
+ });
173
+ });
174
+
175
+ <% end %>
176
+