camaleon_ecommerce 1.1 → 1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (70) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/plugins/ecommerce/admin_product.js.coffee +83 -0
  3. data/app/assets/javascripts/plugins/ecommerce/cart.js +3 -0
  4. data/app/controllers/plugins/ecommerce/admin/coupons_controller.rb +6 -12
  5. data/app/controllers/plugins/ecommerce/admin/orders_controller.rb +2 -8
  6. data/app/controllers/plugins/ecommerce/admin/payment_methods_controller.rb +7 -12
  7. data/app/controllers/plugins/ecommerce/admin/prices_controller.rb +0 -8
  8. data/app/controllers/plugins/ecommerce/admin/settings_controller.rb +0 -8
  9. data/app/controllers/plugins/ecommerce/admin/shipping_methods_controller.rb +6 -14
  10. data/app/controllers/plugins/ecommerce/admin/tax_rates_controller.rb +6 -12
  11. data/app/controllers/plugins/ecommerce/admin_controller.rb +27 -8
  12. data/app/controllers/plugins/ecommerce/front/checkout_controller.rb +42 -75
  13. data/app/controllers/plugins/ecommerce/front/orders_controller.rb +2 -10
  14. data/app/controllers/plugins/ecommerce/front_controller.rb +0 -8
  15. data/app/decorators/plugins/ecommerce/coupon_decorator.rb +0 -8
  16. data/app/decorators/plugins/ecommerce/product_decorator.rb +86 -35
  17. data/app/decorators/plugins/ecommerce/product_item_decorator.rb +27 -3
  18. data/app/decorators/plugins/ecommerce/product_variation_decorator.rb +18 -0
  19. data/app/helpers/plugins/ecommerce/ecommerce_email_helper.rb +11 -13
  20. data/app/helpers/plugins/ecommerce/ecommerce_functions_helper.rb +25 -11
  21. data/app/helpers/plugins/ecommerce/ecommerce_helper.rb +22 -27
  22. data/app/helpers/plugins/ecommerce/ecommerce_payment_helper.rb +1 -56
  23. data/app/models/plugins/ecommerce/attribute.rb +9 -0
  24. data/app/models/plugins/ecommerce/cart.rb +46 -28
  25. data/app/models/plugins/ecommerce/coupon.rb +0 -8
  26. data/app/models/plugins/ecommerce/legacy_cart.rb +50 -0
  27. data/app/models/plugins/ecommerce/legacy_order.rb +48 -0
  28. data/app/models/plugins/ecommerce/order.rb +0 -8
  29. data/app/models/plugins/ecommerce/order_detail.rb +0 -9
  30. data/app/models/plugins/ecommerce/payment_method.rb +0 -8
  31. data/app/models/plugins/ecommerce/product_item.rb +3 -10
  32. data/app/models/plugins/ecommerce/product_variation.rb +9 -0
  33. data/app/models/plugins/ecommerce/shipping_method.rb +0 -8
  34. data/app/models/plugins/ecommerce/tax_rate.rb +0 -8
  35. data/app/services/plugins/ecommerce/cart_service.rb +149 -0
  36. data/app/services/plugins/ecommerce/order_service.rb +26 -0
  37. data/app/services/plugins/ecommerce/product_item_service.rb +29 -0
  38. data/app/services/plugins/ecommerce/product_service.rb +17 -0
  39. data/app/services/plugins/ecommerce/site_service.rb +21 -0
  40. data/app/services/plugins/ecommerce/user_cart_service.rb +12 -0
  41. data/app/services/plugins/ecommerce/user_product_service.rb +29 -0
  42. data/app/services/plugins/ecommerce/util_service.rb +5 -0
  43. data/app/views/plugins/ecommerce/admin/orders/form.html.erb +28 -16
  44. data/app/views/plugins/ecommerce/admin/orders/index.html.erb +7 -1
  45. data/app/views/plugins/ecommerce/admin/payment_methods/form.html.erb +11 -1
  46. data/app/views/plugins/ecommerce/admin/product_attributes.html.erb +95 -0
  47. data/app/views/plugins/ecommerce/admin/products/_variations.html.erb +72 -0
  48. data/app/views/plugins/ecommerce/front/checkout/cart_index.html.erb +5 -5
  49. data/app/views/plugins/ecommerce/front/orders/show.html.erb +96 -89
  50. data/app/views/plugins/ecommerce/partials/_cart_widget.html.erb +3 -3
  51. data/app/views/plugins/ecommerce/partials/checkout/_details.html.erb +1 -1
  52. data/app/views/plugins/ecommerce/partials/checkout/_payments.html.erb +6 -1
  53. data/app/views/plugins/ecommerce/partials/checkout/_products_detail.html.erb +1 -1
  54. data/app/views/plugins/ecommerce/partials/checkout/_user_info.html.erb +26 -22
  55. data/app/views/post_types/commerce/single.html.erb +28 -12
  56. data/config/camaleon_plugin.json +4 -12
  57. data/config/custom_models.rb +10 -0
  58. data/config/locales/en.yml +3 -0
  59. data/config/locales/es.yml +112 -54
  60. data/config/routes.rb +2 -0
  61. data/db/migrate/20160527184747_add_new_cart_structure.rb +7 -4
  62. data/db/migrate/20160620200501_add_product_attributes_structure.rb +21 -0
  63. data/db/migrate/20160825174848_set_cama_post_decorator_class.rb +13 -0
  64. data/db/migrate/20160825232739_migrate_order_data.rb +87 -0
  65. data/lib/ecommerce/version.rb +1 -1
  66. metadata +22 -7
  67. data/app/assets/javascripts/plugins/ecommerce/admin.js +0 -0
  68. data/app/assets/javascripts/plugins/ecommerce/fix_form.js +0 -7
  69. data/config/currency_en.json +0 -154
  70. data/config/currency_es.json +0 -154
@@ -0,0 +1,26 @@
1
+ class Plugins::Ecommerce::OrderService
2
+ def initialize(site, order)
3
+ @site = site
4
+ @order = order
5
+ end
6
+
7
+ attr_reader :site, :order
8
+
9
+ def product_owners
10
+ owners = []
11
+ order.products.each do |product|
12
+ owners << product.owner if product.owner.present?
13
+ end
14
+ owners.uniq
15
+ end
16
+
17
+ def product_files
18
+ files = []
19
+ order.products.each do |product|
20
+ files += product.get_fields('ecommerce_files').map do |f|
21
+ CamaleonCmsLocalUploader::private_file_path(f, site)
22
+ end
23
+ end
24
+ files.uniq
25
+ end
26
+ end
@@ -0,0 +1,29 @@
1
+ class Plugins::Ecommerce::ProductItemService
2
+ def initialize(site, product_item)
3
+ @site = site
4
+ @product_item = product_item
5
+ end
6
+
7
+ attr_reader :site, :product_item
8
+
9
+ def user
10
+ @user ||= product_item.cart.user
11
+ end
12
+
13
+ def product
14
+ @product ||= product_item.product
15
+ end
16
+
17
+ def decrement_qty!
18
+ available_qty = Plugins::Ecommerce::UserProductService.new(
19
+ site, user, product, product_item.variation_id).available_qty
20
+ val = (available_qty - product_item.qty).to_i
21
+ if val >= 0
22
+ if product_item.variation_id.present?
23
+ product_item.product_variation.update_column(:qty, val)
24
+ else
25
+ product.update_field_value('ecommerce_qty', val)
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,17 @@
1
+ class Plugins::Ecommerce::ProductService
2
+ def initialize(site, product, variation_id = nil)
3
+ @site = site
4
+ @product = product
5
+ @variation_id = variation_id
6
+ end
7
+
8
+ attr_reader :site, :product, :variation_id
9
+
10
+ def available_qty
11
+ if variation_id.present?
12
+ product.decorate.get_variation(variation_id).qty || 0
13
+ else
14
+ product.get_field_value('ecommerce_qty').to_f || 0
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ class Plugins::Ecommerce::SiteService
2
+ def initialize(site)
3
+ @site = site
4
+ end
5
+
6
+ attr_reader :site
7
+
8
+ def currency
9
+ site.get_meta("_setting_ecommerce", {})[:current_unit] || 'USD'
10
+ end
11
+
12
+ def payment_method(type)
13
+ payment_method = site.payment_methods.actives.detect do |payment_method|
14
+ payment_method.get_option('type') == type
15
+ end
16
+ if payment_method.nil?
17
+ raise ArgumentError, "Payment method #{type} is not found"
18
+ end
19
+ payment_method
20
+ end
21
+ end
@@ -0,0 +1,12 @@
1
+ class Plugins::Ecommerce::UserCartService
2
+ def initialize(site, user)
3
+ @site = site
4
+ @user = user
5
+ end
6
+
7
+ attr_reader :site, :user
8
+
9
+ def get_cart
10
+ site.carts.set_user(user).active_cart.first_or_create(name: "Cart by #{user.id}").decorate
11
+ end
12
+ end
@@ -0,0 +1,29 @@
1
+ class Plugins::Ecommerce::UserProductService
2
+ def initialize(site, user, product, variation_id = nil)
3
+ @site = site
4
+ @user = user
5
+ @product = product
6
+ @variation_id = variation_id
7
+ end
8
+
9
+ attr_reader :site, :user, :product, :variation_id
10
+
11
+ def available_qty
12
+ available_qty = Plugins::Ecommerce::ProductService.new(
13
+ site, product, variation_id).available_qty
14
+ available_qty -= qty_in_carts
15
+ end
16
+
17
+ private
18
+
19
+ def qty_in_carts
20
+ carts = site.carts.where.not(user_id: user.id).active_cart.joins(:product_items)
21
+ if variation_id.present?
22
+ carts.where("#{Plugins::Ecommerce::ProductItemDecorator.table_name}" =>
23
+ {variation_id: variation_id}).sum("#{Plugins::Ecommerce::ProductItem.table_name}.qty")
24
+ else
25
+ carts.where("#{Plugins::Ecommerce::ProductItemDecorator.table_name}" =>
26
+ {product_id: product.id}).sum("#{Plugins::Ecommerce::ProductItem.table_name}.qty")
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,5 @@
1
+ class Plugins::Ecommerce::UtilService
2
+ def self.ecommerce_money_to_cents(money)
3
+ (money*100).round
4
+ end
5
+ end
@@ -1,20 +1,32 @@
1
1
  <div class="panel panel-default">
2
- <div class="panel-heading">
3
- <h4><span class="fa fa-cog"></span> <%= t('plugin.ecommerce.edit_order') %>: <%= @order.slug %></h4>
4
- </div>
5
- <%= form_for @order, url: {action: @order.new_record? ? :create : :update}, html: {class: 'form-order', id: 'form-order'} do |f| %>
6
- <div class="panel-body">
7
- <%= render plugin_view('partials/checkout/user_info'), cart: @order, as_partial: true %>
8
- <hr>
9
- <div class="form-group">
10
- <%= f.label nil, t('plugin.ecommerce.show_order.consignment_number', default: 'Consignment Number') %>
11
- <%= text_field_tag 'metas[consignment_number]', @order.get_meta('consignment_number'), class: 'form-control' %>
2
+ <div class="panel-heading">
3
+ <h4><span class="fa fa-cog"></span> <%= t('plugin.ecommerce.edit_order') %>: <%= @order.slug %></h4>
4
+ </div>
5
+ <%= form_for @order, url: {action: @order.new_record? ? :create : :update}, html: {class: 'form-order', id: 'form-order'} do |f| %>
6
+ <div class="panel-body">
7
+ <%= render plugin_view('partials/checkout/user_info'), cart: @order, as_partial: true %>
8
+ <hr>
9
+ <div class="form-group">
10
+ <%= f.label nil, t('plugin.ecommerce.show_order.consignment_number', default: 'Consignment Number') %>
11
+ <%= text_field_tag 'metas[consignment_number]', @order.get_meta('consignment_number'), class: 'form-control' %>
12
+ </div>
13
+ <div class="form-group">
14
+ <%= f.label nil, t('plugins.ecommerce.front.orders.show.date_shipped', default: 'Date Shipped') %>
15
+ <div class="input-group date date-input-box">
16
+ <%= f.text_field :shipped_at, class: 'form-control' %>
17
+ <span class="add-on input-group-addon"><span class="glyphicon glyphicon-calendar"></span></span>
18
+ </div>
19
+ </div>
12
20
  </div>
13
- </div>
14
21
 
15
- <div class="panel-footer">
16
- <button class="btn btn-default" onclick="history.back()"><%= t('camaleon_cms.admin.button.back') %></button>
17
- <button class="btn btn-primary pull-right"><%= t('camaleon_cms.admin.button.update') %></button>
18
- </div>
19
- <% end %>
22
+ <div class="panel-footer">
23
+ <button class="btn btn-default" onclick="history.back()"><%= t('camaleon_cms.admin.button.back') %></button>
24
+ <button class="btn btn-primary pull-right"><%= t('camaleon_cms.admin.button.update') %></button>
25
+ </div>
26
+ <script>
27
+ jQuery(function () {
28
+ $('#form-order').find('#plugins_ecommerce_order_shipped_at').parent().datetimepicker({ format: 'YYYY-MM-DD HH:mm' });;
29
+ })
30
+ </script>
31
+ <% end %>
20
32
  </div>
@@ -88,7 +88,13 @@
88
88
  %>
89
89
  <tr>
90
90
  <td><%= order.slug %></td>
91
- <td><%= order.user.fullname %></td>
91
+ <td>
92
+ <% if order.user %>
93
+ <%= order.user.fullname %>
94
+ <% else %>
95
+ <small>(No user)</small>
96
+ <% end %>
97
+ </td>
92
98
  <td><%= raw order.the_status %></td>
93
99
  <td><%= order.paid? ? 'Yes' : 'No' %></td>
94
100
  <td>
@@ -30,9 +30,11 @@
30
30
  <ul class="nav nav-tabs nav-justified">
31
31
  <li class="<%= 'active' if options[:type] == 'bank_transfer' %>"><a href="#tab8" data-toggle="tab"><%= t('plugin.ecommerce.by_bank_transfer') %></a></li>
32
32
  <li class="<%= 'active' if options[:type] == 'paypal' %>"><a href="#tab9" data-toggle="tab"><%= t('plugin.ecommerce.by_paypal') %></a></li>
33
- <!--<li class="<%= 'active' if options[:type] == 'credit_card' %>"><a href="#tab7" data-toggle="tab"><%= t('plugin.ecommerce.by_credit_card') %></a></li>-->
34
33
  <li class="<%= 'active' if options[:type] == 'authorize_net' %>"><a href="#tab10" data-toggle="tab"><%= t('plugin.ecommerce.by_authorize_net') %></a></li>
35
34
  <li class="<%= 'active' if options[:type] == 'stripe' %>"><a href="#tab11" data-toggle="tab"><%= t('plugin.ecommerce.by_stripe', default: 'Stripe') %></a></li>
35
+ <% ecommerce_custom_payment_methods.each do |k, obj| %>
36
+ <li class="<%= 'active' if options[:type] == k %>"><a href="#tab_<%= k %>" data-toggle="tab"><%= obj[:title] %></a></li>
37
+ <% end %>
36
38
  </ul>
37
39
  <div class="panel-body tab-content">
38
40
 
@@ -115,6 +117,14 @@
115
117
  <%= text_field_tag('options[stripe_key]', options[:stripe_key], class: 'form-control required') %>
116
118
  </div>
117
119
  </div>
120
+
121
+ <% ecommerce_custom_payment_methods.each do |k, obj| %>
122
+ <div class="tab-pane <%= 'active' if options[:type] == k %>" id="tab_<%= k %>">
123
+ <%= hidden_field_tag('options[type]', k) %>
124
+ <%= render obj[:settings_view_path], options: options %>
125
+ </div>
126
+ <% end %>
127
+
118
128
  </div>
119
129
  </div>
120
130
 
@@ -0,0 +1,95 @@
1
+ <%= form_tag url_for(action: :save_product_attributes), class: 'panel panel-default', id: 'ecommerce_product_attributes', 'data-confirm-msg' => t('.confirm_delete', default: 'Are you sure to delete?') do %>
2
+ <div class="panel-heading ui-draggable-handle">
3
+ <h3 class="panel-title"><%= t('.title', default: 'Product Attributes') %></h3>
4
+ </div>
5
+ <div class="panel-body">
6
+ <% (current_site.product_attributes.to_a + [Plugins::Ecommerce::Attribute.new]).each_with_index do |attr, index| %>
7
+ <div data-id="<%= attr.id %>" class="panel panel-info attribute_group attribute_<%= attr.id %> <%= 'hidden' unless attr.id.present? %>">
8
+ <div class="panel-heading">
9
+ <h3 class="panel-title">&nbsp;</h3>
10
+ <ul class="panel-controls">
11
+ <li><a href="#" class="del_group"><i class="fa fa-times"></i></a></li>
12
+ <li><a class="hidden group_sorter"><i class="fa fa-arrows" style="cursor: move"></i></a></li>
13
+ <li><a class="panel-collapse" href="#"><span class="fa fa-angle-down"></span></a></li>
14
+ </ul>
15
+ </div>
16
+ <div class="panel-body">
17
+ <div class="form-group">
18
+ <label><%= t('.group_label', default: 'Group Label') %></label>
19
+ <%= text_field_tag "attribute_names[#{attr.id}][label]", attr.label, class: 'form-control translatable required' %>
20
+ </div>
21
+ <label><%= t('.values', default: 'Values') %></label>
22
+ <hr>
23
+ <div class="item-custom-field">
24
+ <div class="actions"></div>
25
+ <div class="row group-input-fields-content">
26
+ <div class="col-md-4">
27
+ <label><%= t('.code', default: 'Code') %></label><em class="text-danger">*</em><br>
28
+ </div>
29
+ <div class="col-md-8">
30
+ <label><%= t('.value', default: 'Value') %></label><em class="text-danger">*</em><br>
31
+ </div>
32
+ </div>
33
+ </div>
34
+ <ul class="values_sortable">
35
+ <% (attr.values.to_a + (attr.id.present? ? [] : [Plugins::Ecommerce::Attribute.new])).each do |value| %>
36
+ <li class="item-custom-field product_attribute_value_<%= value.id %>">
37
+ <%= hidden_field_tag "attribute[#{attr.id}][][position]", value.position, class: 'value_position' %>
38
+ <%= hidden_field_tag "attribute[#{attr.id}][][id]", value.id %>
39
+ <div class="actions">
40
+ <i style="cursor: move" class="fa fa-arrows values_sorter"></i>
41
+ <a href="#" class="del"><i class="fa fa-times"></i></a>
42
+ </div>
43
+ <div class="group-input-fields-content row">
44
+ <div class="col-md-4">
45
+ <%= text_field_tag "attribute[#{attr.id}][][key]", value.key, class: 'form-control slug required', "data-parent" => "category_name", style: "#{'margin-top: 47px;' if current_site.get_languages.count > 1 }" %>
46
+ </div>
47
+ <div class="col-md-8">
48
+ <%= text_field_tag "attribute[#{attr.id}][][value]", value.label, class: 'form-control required translatable' %>
49
+ </div>
50
+ </div>
51
+ </li>
52
+ <% end %>
53
+ </ul>
54
+ <div> <a href="#" class="btn btn-warning btn-xs add_new_value"> <i class="fa fa-plus"></i> <%= t('.add_new_value', default: 'Add new value') %></a></div>
55
+ </div>
56
+ </div>
57
+ <% end %>
58
+
59
+ </div>
60
+ <div class="panel-footer text-right">
61
+ <a class="btn btn-default pull-left" href="<%= url_for action: :index %>" role="back"><%= t('camaleon_cms.admin.button.back', default: 'Back')%></a>
62
+ <a class="btn btn-default add_new_group"><%= t('.add_attr_group', default: 'Add new group')%></a>
63
+ <button class="btn btn-primary" type="submit"><%= t('camaleon_cms.admin.button.submit', default: 'Save')%></button>
64
+ </div>
65
+ <% end %>
66
+ <script>
67
+ jQuery(function(){
68
+ var groups_counter = 1;
69
+ var panel = $('#ecommerce_product_attributes');
70
+ var val_cache = panel.find('.product_attribute_value_').remove().clone();
71
+ var p_cache = panel.find('.panel.attribute_').remove().clone().removeClass('hidden');
72
+ var after_reorder = function(){ $(this).children().each(function(index){ $(this).find('input.value_position').val(index); }) }
73
+ panel.find('.add_new_group').click(function(){
74
+ var g = p_cache.clone().attr('data-id', 'new_'+groups_counter);
75
+ panel.children('.panel-body').append(g);
76
+ g.find('input').each(function(){ $(this).attr('name', $(this).attr('name').replace('[]', '['+g.attr('data-id')+']')) });
77
+ g.find('.translatable').Translatable();
78
+ g.find('.add_new_value').click();
79
+ g.find('.values_sortable').sortable({handle: '.values_sorter', update: after_reorder})
80
+ return false;
81
+ });
82
+
83
+ panel.on('click', '.add_new_value', function(){
84
+ var g = $(this).closest('.attribute_group');
85
+ var clone = val_cache.clone();
86
+ clone.find('input').each(function(){ $(this).attr('name', $(this).attr('name').replace('[]', '['+g.attr('data-id')+']')) });
87
+ clone.find('.translatable').Translatable();
88
+ g.find('.panel-body > ul').append(clone);
89
+ return false;
90
+ });
91
+ panel.find('.values_sortable').sortable({handle: '.values_sorter', update: after_reorder})
92
+ panel.on('click', '.item-custom-field a.del', function(){ if(!confirm(panel.attr('data-confirm-msg'))) return false; $(this).closest('li').fadeOut('slow', function(){ $(this).remove(); }); return false; });
93
+ panel.on('click', 'a.del_group', function(){ if(!confirm(panel.attr('data-confirm-msg'))) return false; $(this).closest('.attribute_group').fadeOut('slow', function(){ $(this).remove(); }); return false; });
94
+ });
95
+ </script>
@@ -0,0 +1,72 @@
1
+ <% field = post_type.get_field_object('ecommerce_photos') %>
2
+ <div class="panel panel-default hidden" id="product_variations" data-confirm-msg="<%= t('.confirm_del', default: 'Are you sure to delete this variation?') %>">
3
+ <div class="panel-heading ">
4
+ <h3 class="panel-title"><%= t('.title', default: 'Product Variations') %></h3>
5
+ </div>
6
+ <div class="panel-body variations_sortable">
7
+ <% (product.product_variations.to_a + [Plugins::Ecommerce::ProductVariation.new]).each do |variation| %>
8
+ <div class="panel panel-info product_variation <%= 'blank_product_variation hidden' unless variation.id.present? %>" data-id="<%= variation.id %>">
9
+ <div class="panel-heading">
10
+ <h3 class="panel-title">&nbsp;</h3>
11
+ <ul class="panel-controls">
12
+ <li><a class="var_del" href="#"><i class="fa fa-times text-danger"></i></a></li>
13
+ <li><a class="variation_sorter"><i class="fa fa-arrows" style="cursor: move"></i></a></li>
14
+ <li><a class="panel-collapse" href="#"><span class="fa fa-angle-down"></span></a></li>
15
+ </ul>
16
+ </div>
17
+ <div class="panel-body">
18
+ <%= hidden_field_tag "product_variation[#{variation.id}][position]", variation.position, class: 'product_variation_position' %>
19
+ <div class="variation_attributes form-group">
20
+ <label><%= t('.attributes', default: 'Attributes') %></label>
21
+ <ul class="item-custom-field sortable_values">
22
+ <% (variation.id.present? ? variation.attribute_values : [variation.attribute_values.rewhere(id: nil).new]).each do |val| %>
23
+ <li>
24
+ <div class="actions">
25
+ <a class="val_sorter"><i class="fa fa-arrows" style="cursor: move"></i></a>
26
+ <a href="#" class="val_del "><i class="fa fa-times text-danger"></i></a>
27
+ </div>
28
+ <div class="row group-input-fields-content">
29
+ <div class="col-md-4">
30
+ <%= select_tag "product_variation[#{variation.id}][attributes][][id]", options_from_collection_for_select(current_site.product_attributes, :id, :label, val.parent_id), class: 'form-control required product_attribute_select' %>
31
+ </div>
32
+ <div class="col-md-8">
33
+ <%= select_tag "product_variation[#{variation.id}][attributes][][value]", val.id.present? ? options_from_collection_for_select(val.product_attribute.values, :id, :label, val.id) : [], class: 'form-control required product_attribute_vals_select' %>
34
+ </div>
35
+ </div>
36
+ </li>
37
+ <% end %>
38
+ </ul>
39
+ <div> <a href="#" class="btn btn-warning btn-xs add_new_value"> <i class="fa fa-plus"></i> <%= t('.add_new_value', default: 'Add new value') %></a></div>
40
+ </div>
41
+ <div class="form-group">
42
+ <label><%= t('.photo', default: 'Photo') %></label><em class="text-danger">*</em><br>
43
+ <div class=" input-group">
44
+ <%= url_field_tag "product_variation[#{variation.id}][photo]", variation.photo, data:{dimension: field.options[:dimension], versions: field.options[:versions], thumb_size: field.options[:thumb_size]}, class: 'data-error-place-parent form-control required' %>
45
+ <a href="#" class="input-group-addon product_variation_photo_link"><i class="fa fa-upload"></i> <%= t('camaleon_cms.admin.button.upload_image', default: 'Upload Photo')%> <%= "(#{field.get_option('dimension')})" if field.get_option('dimension').present? %></a>
46
+ </div>
47
+ </div>
48
+ <div class="form-group">
49
+ <label><%= t('.sku', default: 'SKU') %></label><em class="text-danger">*</em><br>
50
+ <%= text_field_tag "product_variation[#{variation.id}][sku]", variation.sku, class: 'form-control required' %>
51
+ </div>
52
+ <div class="form-group">
53
+ <label><%= t('.price', default: 'Price') %></label><em class="text-danger">*</em><br>
54
+ <%= number_field_tag "product_variation[#{variation.id}][price]", variation.amount, class: 'form-control required number' %>
55
+ </div>
56
+ <div class="form-group">
57
+ <label><%= t('.weight', default: 'Weight') %></label><em class="text-danger">*</em><br>
58
+ <%= number_field_tag "product_variation[#{variation.id}][weight]", variation.weight, class: 'form-control required number' %>
59
+ </div>
60
+ <div class="form-group">
61
+ <label><%= t('.qty', default: 'Quantity') %></label>
62
+ <%= number_field_tag "product_variation[#{variation.id}][qty]", variation.qty, class: 'form-control number' %>
63
+ </div>
64
+ </div>
65
+ </div>
66
+ <% end %>
67
+ </div>
68
+ <div class="panel-footer text-right">
69
+ <a class="btn btn-warning add_new_variation btn-xs" href="#"><i class="fa fa-plus"></i> <%= t('.add_new_variation', default: 'Add new variation') %></a>
70
+ </div>
71
+ </div>
72
+ <script>var PRODUCT_ATTRIBUTES = <%= raw current_site.product_attributes.to_json(include: :values) %></script>
@@ -16,16 +16,16 @@
16
16
  <tbody>
17
17
  <% @products.each do |item| product = item.product.decorate %>
18
18
  <tr>
19
- <td><a href="<%= product.the_url %>"><%= product.the_title %></a></td>
19
+ <td><a href="<%= product.the_url %>"><%= product.the_variation_title(item.variation_id) %></a></td>
20
20
  <td><%= item.the_price %></td>
21
- <td><%= product.the_tax %></td>
21
+ <td><%= item.the_tax %></td>
22
22
  <td>
23
- <input name="products[][product_id]" type="hidden" value="<%= product.id %>"/>
24
- <input class="text-qty" type="number" name="products[][qty]" value="<%= item.qty %>">
23
+ <input name="product_items[][item_id]" type="hidden" value="<%= item.id %>"/>
24
+ <input class="text-qty" type="number" name="product_items[][qty]" value="<%= item.qty %>">
25
25
  </td>
26
26
  <td><%= item.the_sub_total %></td>
27
27
  <td>
28
- <a rel="nofollow" data-method="delete" href="<%= plugins_ecommerce_checkout_cart_remove_path(product_id: product.id) %>"><%= t('.delete', default: 'Remove') %></a>
28
+ <a rel="nofollow" data-method="delete" href="<%= plugins_ecommerce_checkout_cart_remove_path(product_item_id: item.id) %>"><%= t('.delete', default: 'Remove') %></a>
29
29
  </td>
30
30
  </tr>
31
31
  <% end %>
@@ -1,17 +1,20 @@
1
1
  <% order ||= @order %>
2
2
  <div class="order_details">
3
- <% unless defined?(as_partial) %>
4
- <h1><%= t('.title', default: 'Order Details') %>: <%= order.slug %></h1>
5
- <% end %>
6
- <div class="row">
7
- <div class="col-md-6">
8
- <h4><%= t('.customer_info', default: 'Customer Info') %></h4>
9
- <ul class="ec-list-orders-address">
10
- <li><strong><%= t('.name', default: 'Name') %>:</strong> <span> <%= order.user.fullname %></span></li>
11
- <li><strong><%= t('.email', default: 'Email') %>:</strong> <span> <%= order.user.email %></span></li>
12
- <li><strong><%= t('.phone', default: 'Phone') %>:</strong> <span> <%= order.user.get_option('phone') %></span></li>
13
- </ul>
3
+ <% unless defined?(as_partial) %>
4
+ <h1><%= t('.title', default: 'Order Details') %>: <%= order.slug %></h1>
5
+ <% end %>
6
+ <div>
7
+ <h4><%= t('.customer_info', default: 'Customer Info') %></h4>
8
+ <ul class="ec-list-orders-address">
9
+ <li><strong><%= t('.name', default: 'Name') %>:</strong> <span> <%= order.user.fullname %></span></li>
10
+ <li><strong><%= t('.email', default: 'Email') %>:</strong> <span> <%= order.user.email %></span></li>
11
+ <li><strong><%= t('.phone', default: 'Phone') %>:</strong>
12
+ <span> <%= order.user.get_option('phone') %></span></li>
13
+ </ul>
14
+ </div>
14
15
 
16
+ <div class="row">
17
+ <div class="col-md-6">
15
18
  <h4><%= t('.billing_address', default: 'Billing Address') %></h4>
16
19
  <% detail = order.get_meta("billing_address", {}) %>
17
20
  <ul class="ec-list-orders-address">
@@ -21,11 +24,13 @@
21
24
  <li><strong><%= t('.state', default: 'State') %>:</strong> <%= detail[:state] %></li>
22
25
  <li><strong><%= t('.zip_code', default: 'Zip code') %>:</strong> <%= detail[:zip] %></li>
23
26
  <li><strong><%= t('.country', default: 'Country') %>:</strong> <%= detail[:country] %></li>
27
+ <li><strong><%= t('.phone_number', default: 'Phone Number') %>:</strong> <%= detail[:phone_number] %>
28
+ </li>
24
29
  </ul>
25
30
  </div>
26
31
  <div class="col-md-6">
27
- <h4><%= t('.shipping_address', default: 'Shipping Address') %></h4>
28
- <% detail = order.get_meta("shipping_address", {}) %>
32
+ <h4><%= t('.shipping_address', default: 'Shipping Address') %></h4>
33
+ <% detail = order.get_meta("shipping_address", {}) %>
29
34
  <ul class="ec-list-orders-address">
30
35
  <li><strong><%= t('.address', default: 'Address1') %>:</strong> <%= detail[:address1] %></li>
31
36
  <li><strong><%= t('.address', default: 'Address') %>2:</strong> <%= detail[:address2] %></li>
@@ -33,98 +38,100 @@
33
38
  <li><strong><%= t('.state', default: 'State') %>:</strong> <%= detail[:state] %></li>
34
39
  <li><strong><%= t('.zip_code', default: 'Zip code') %>:</strong> <%= detail[:zip] %></li>
35
40
  <li><strong><%= t('.country', default: 'Country') %>:</strong> <%= detail[:country] %></li>
41
+ <li><strong><%= t('.phone_number', default: 'Phone Number') %>:</strong> <%= detail[:phone_number] %>
42
+ </li>
36
43
  </ul>
37
44
  </div>
38
- </div>
45
+ </div>
39
46
 
40
- <div class="row">
41
- <div class="col-md-12">
42
- <h4><%= t('.title_products', default: 'Products and Payments') %></h4>
43
- <div id="totals_section">
44
- <table class="table table-bordered">
45
- <tbody>
46
- <tr>
47
- <th id="quantity_col"><%= t('.qty', default: 'Quantity') %></th>
48
- <th id="item_col"><%= t('.item', default: 'Item') %></th>
49
- <th id="price_col"><%= t('.price', default: 'Price') %></th>
47
+ <div class="row">
48
+ <div class="col-md-12">
49
+ <h4><%= t('.title_products', default: 'Products and Payments') %></h4>
50
+ <div id="totals_section">
51
+ <table class="table table-bordered">
52
+ <tbody>
53
+ <tr>
54
+ <th id="quantity_col"><%= t('.qty', default: 'Quantity') %></th>
55
+ <th id="item_col"><%= t('.item', default: 'Item') %></th>
56
+ <th id="price_col"><%= t('.price', default: 'Price') %></th>
50
57
 
51
- <th id="tax_col"><%= t('.tax', default: 'Tax') %></th>
52
- <th id="subtotal_col"><%= t('.subtotal', default: 'Sub Total') %></th>
53
- </tr>
54
- <% order.product_items.each do |item| %>
58
+ <th id="tax_col"><%= t('.tax', default: 'Tax') %></th>
59
+ <th id="subtotal_col"><%= t('.subtotal', default: 'Sub Total') %></th>
60
+ </tr>
61
+ <% order.product_items.each do |item| %>
62
+ <tr>
63
+ <td><%= item.qty %></td>
64
+ <td><%= link_to(item.cache_the_title, item.product.try(:decorate).try(:the_url)) %></td>
65
+ <td><%= item.cache_the_price %></td>
66
+ <td><%= item.cache_the_tax %></td>
67
+ <td><%= item.cache_the_sub_total %></td>
68
+ </tr>
69
+ <% end %>
55
70
  <tr>
56
- <td><%= item.qty %></td>
57
- <td><%= item.cache_the_title %></td>
58
- <td><%= item.cache_the_price %></td>
59
- <td><%= item.cache_the_tax %></td>
60
- <td><%= item.cache_the_sub_total %></td>
71
+ <td colspan="2"></td>
72
+ <td colspan="2" class="text-right"><%= t('.total_excl', default: 'Total (excluding Tax)') %> </td>
73
+ <td><%= order.cache_the_sub_total %></td>
61
74
  </tr>
62
- <% end %>
63
- <tr>
64
- <td colspan="2"></td>
65
- <td colspan="2" class="text-right"><%= t('.total_excl', default: 'Total (excluding Tax)') %> </td>
66
- <td><%= order.cache_the_sub_total %></td>
67
- </tr>
75
+ <tr>
76
+ <td colspan="2"></td>
77
+ <td colspan="2" class="text-right"><%= t('.tax', default: 'Tax') %></td>
78
+ <td id="tax_total"><%= order.cache_the_tax %></td>
79
+ </tr>
80
+ <tr>
81
+ <td colspan="2"></td>
82
+ <td colspan="2" class="text-right"><%= t('.discount', default: 'Discount') %></td>
83
+ <td><%= order.cache_the_discounts %></td>
84
+ </tr>
85
+ <tr>
86
+ <td colspan="2"></td>
87
+ <td colspan="2" class="text-right"><%= t('.total_shipping', default: 'Total shipping') %></td>
88
+ <td><%= order.cache_the_shipping %></td>
89
+ </tr>
90
+ <tr>
91
+ <td colspan="2"></td>
92
+ <td colspan="2" class="text-right"><%= t('.total_price', default: 'Total Price') %></td>
93
+ <td><%= order.cache_the_total %></td>
94
+ </tr>
95
+ </tbody>
96
+ </table>
97
+ </div>
98
+
99
+ <table class="table table-bordered">
100
+ <tbody>
68
101
  <tr>
69
- <td colspan="2"></td>
70
- <td colspan="2" class="text-right"><%= t('.tax', default: 'Tax') %></td>
71
- <td id="tax_total"><%= order.cache_the_tax %></td>
102
+ <th><%= t('.payment_type', default: 'Type Payment') %></th>
103
+ <th></th>
72
104
  </tr>
73
105
  <tr>
74
- <td colspan="2"></td>
75
- <td colspan="2" class="text-right"><%= t('.discount', default: 'Discount') %></td>
76
- <td><%= order.cache_the_discounts %></td>
106
+ <td><%= order.payment_method.name rescue 'Not Payment' %></td>
107
+ <td><%= raw order.the_status %></td>
77
108
  </tr>
109
+ <% if defined?(as_partial) %>
110
+ <tr>
111
+ <td>
112
+ <%= raw order.get_meta('payment_data', {}).map { |k, v| "<b>#{k.to_s.titleize}</b>: #{v}" }.join('<br>') %>
113
+ </td>
114
+ </tr>
115
+ <% end %>
116
+ </tbody>
117
+ </table>
118
+
119
+ <table class="table table-bordered">
120
+ <tbody>
78
121
  <tr>
79
- <td colspan="2"></td>
80
- <td colspan="2" class="text-right"><%= t('.total_shipping', default: 'Total shipping') %></td>
81
- <td><%= order.cache_the_shipping %></td>
122
+ <th><%= t('.shipping_method', default: 'Shipping Method') %></th>
123
+ <th><%= t('.date_shipped', default: 'Shipped Date') %></th>
124
+ <th><%= t('.track_url', default: 'URL Tracking') %></th>
82
125
  </tr>
83
126
  <tr>
84
- <td colspan="2"></td>
85
- <td colspan="2" class="text-right"><%= t('.total_price', default: 'Total Price') %></td>
86
- <td><%= order.cache_the_total %></td>
127
+ <td><%= order.shipping_method.name rescue t('.no_shipping', default: 'Not Shipped Assigned') %></td>
128
+ <td><%= order.shipped_at.presence || t('.no_shipped', default: 'Not Shipped') %></td>
129
+ <td><%= order.the_url_tracking %></td>
87
130
  </tr>
88
131
  </tbody>
89
132
  </table>
133
+ <div class="text-center">
134
+ </div>
90
135
  </div>
91
-
92
- <table class="table table-bordered">
93
- <tbody>
94
- <tr>
95
- <th><%= t('.payment_type', default: 'Type Payment') %></th>
96
- <th></th>
97
- </tr>
98
- <tr>
99
- <td><%= order.payment_method.name rescue 'Not Payment' %></td>
100
- <td><%= raw order.the_status %></td>
101
- </tr>
102
- <% if defined?(as_partial) %>
103
- <tr>
104
- <td>
105
- <%= raw order.get_meta('payment_data', {}).map{|k, v| "<b>#{k.to_s.titleize}</b>: #{v}" }.join('<br>') %>
106
- </td>
107
- </tr>
108
- <% end %>
109
- </tbody>
110
- </table>
111
-
112
- <table class="table table-bordered">
113
- <tbody>
114
- <tr>
115
- <th><%= t('.shipping_method', default: 'Shipping Method') %></th>
116
- <th><%= t('.date_shipped', default: 'Shipped Date') %></th>
117
- <th><%= t('.track_url', default: 'URL Tracking') %></th>
118
- </tr>
119
- <tr>
120
- <td><%= order.shipping_method.name rescue t('.no_shipping', default: 'Not Shipped Assigned') %></td>
121
- <td><%= order.shipped_at.presence || t('.no_shipped', default: 'Not Shipped') %></td>
122
- <td><%= order.the_url_tracking %></td>
123
- </tr>
124
- </tbody>
125
- </table>
126
- <div class="text-center">
127
- </div>
128
136
  </div>
129
- </div>
130
137
  </div>