piggybak 0.5.5 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. data/README.md +32 -25
  2. data/VERSION +1 -1
  3. data/app/assets/javascripts/piggybak.js +11 -1
  4. data/app/assets/javascripts/piggybak.states.js +6 -5
  5. data/app/controllers/piggybak/orders_controller.rb +14 -22
  6. data/app/models/piggybak/address.rb +4 -1
  7. data/app/models/piggybak/adjustment.rb +1 -25
  8. data/app/models/piggybak/cart.rb +18 -17
  9. data/app/models/piggybak/line_item.rb +106 -19
  10. data/app/models/piggybak/order.rb +94 -108
  11. data/app/models/piggybak/payment.rb +25 -27
  12. data/app/models/piggybak/payment_method.rb +3 -1
  13. data/app/models/piggybak/payment_method_value.rb +3 -1
  14. data/app/models/piggybak/{variant.rb → sellable.rb} +6 -4
  15. data/app/models/piggybak/shipment.rb +4 -10
  16. data/app/models/piggybak/shipping_calculator/flat_rate.rb +4 -0
  17. data/app/models/piggybak/shipping_calculator/free.rb +4 -0
  18. data/app/models/piggybak/shipping_calculator/range.rb +4 -0
  19. data/app/models/piggybak/shipping_method.rb +1 -1
  20. data/app/models/piggybak/tax_method.rb +1 -1
  21. data/app/views/piggybak/cart/_form.html.erb +7 -7
  22. data/app/views/piggybak/cart/_items.html.erb +14 -5
  23. data/app/views/piggybak/notifier/order_notification.text.erb +10 -2
  24. data/app/views/piggybak/orders/_details.html.erb +14 -5
  25. data/app/views/piggybak/orders/_google_analytics.html.erb +3 -3
  26. data/app/views/piggybak/orders/download.text.erb +6 -6
  27. data/app/views/piggybak/orders/submit.html.erb +55 -49
  28. data/app/views/rails_admin/main/_location_select.html.haml +3 -3
  29. data/app/views/rails_admin/main/_order_details.html.erb +12 -24
  30. data/app/views/rails_admin/main/_polymorphic_nested.html.haml +29 -0
  31. data/bin/piggybak +12 -0
  32. data/config/routes.rb +0 -2
  33. data/db/migrate/20121008160425_rename_variants_to_sellables.rb +11 -0
  34. data/db/migrate/20121008175144_line_item_rearchitecture.rb +96 -0
  35. data/lib/acts_as_sellable.rb +21 -0
  36. data/lib/formatted_changes.rb +2 -2
  37. data/lib/piggybak.rb +80 -126
  38. data/lib/piggybak/cli.rb +81 -0
  39. data/lib/piggybak/config.rb +21 -0
  40. data/piggybak.gemspec +10 -7
  41. data/spec/dummy_app/app/models/image.rb +1 -1
  42. data/spec/factories.rb +1 -1
  43. metadata +52 -49
  44. data/app/controllers/piggybak/payments_controller.rb +0 -14
  45. data/app/views/rails_admin/main/_order_notes.html.erb +0 -1
  46. data/app/views/rails_admin/main/_payment_refund.html.haml +0 -6
  47. data/lib/acts_as_variant.rb +0 -15
@@ -2,6 +2,10 @@ module Piggybak
2
2
  class ShippingCalculator::FlatRate
3
3
  KEYS = ["rate"]
4
4
 
5
+ def self.description
6
+ "Flat Rate"
7
+ end
8
+
5
9
  def self.available?(*args)
6
10
  true
7
11
  end
@@ -2,6 +2,10 @@ module Piggybak
2
2
  class ShippingCalculator::Free
3
3
  KEYS = []
4
4
 
5
+ def self.description
6
+ "Free Shipping"
7
+ end
8
+
5
9
  def self.available?(method, object)
6
10
  true
7
11
  end
@@ -2,6 +2,10 @@ module Piggybak
2
2
  class ShippingCalculator::Range
3
3
  KEYS = ["cost", "upper", "lower"]
4
4
 
5
+ def self.description
6
+ "Cost per Range"
7
+ end
8
+
5
9
  def self.available?(method, object)
6
10
  low_end = method.metadata.detect { |m| m.key == "lower" }.value
7
11
  high_end = method.metadata.detect { |m| m.key == "upper" }.value
@@ -23,7 +23,7 @@ module Piggybak
23
23
  end
24
24
 
25
25
  def klass_enum
26
- Piggybak.config.shipping_calculators
26
+ Piggybak.config.shipping_calculators.collect { |b| [ b.constantize.description, b ] }
27
27
  end
28
28
 
29
29
  def self.available_methods(cart)
@@ -35,7 +35,7 @@ module Piggybak
35
35
  total_tax += calculator.rate(tax_method, object)
36
36
  end
37
37
  end
38
-
38
+
39
39
  total_tax
40
40
  end
41
41
 
@@ -1,14 +1,14 @@
1
- <% if object.reflections.keys.include?(:piggybak_variant) -%>
2
- <% if object.piggybak_variant && object.piggybak_variant.active -%>
3
- <% if object.piggybak_variant.quantity > 0 || object.piggybak_variant.unlimited_inventory -%>
1
+ <% if object.reflections.keys.include?(:piggybak_sellable) -%>
2
+ <% if object.piggybak_sellable && object.piggybak_sellable.active -%>
3
+ <% if object.piggybak_sellable.quantity > 0 || object.piggybak_sellable.unlimited_inventory -%>
4
4
  <%= form_tag piggybak.cart_add_url do -%>
5
- <div id="variant_details">
6
- <span id="title"><%= object.piggybak_variant.description %></span>
7
- <span id="price"><%= number_to_currency object.piggybak_variant.price %></span>
5
+ <div id="sellable_details">
6
+ <span id="title"><%= object.piggybak_sellable.description %></span>
7
+ <span id="price"><%= number_to_currency object.piggybak_sellable.price %></span>
8
8
  </div>
9
9
  <label>Quantity</label>
10
10
  <%= text_field_tag :quantity, "1" %>
11
- <%= hidden_field_tag :variant_id, object.piggybak_variant.id %>
11
+ <%= hidden_field_tag :sellable_id, object.piggybak_sellable.id %>
12
12
  <%= submit_tag "Add to Cart", :id => "submit" %>
13
13
  <% end -%>
14
14
  <% else -%>
@@ -12,19 +12,19 @@
12
12
  </tr>
13
13
  <% @cart.items.each do |item| %>
14
14
  <tr>
15
- <td><%= item[:variant].description %></td>
16
- <td><%= number_to_currency item[:variant].price %></td>
15
+ <td><%= item[:sellable].description %></td>
16
+ <td><%= number_to_currency item[:sellable].price %></td>
17
17
  <td>
18
18
  <% if page == "cart" -%>
19
- <%= text_field_tag "quantity[#{item[:variant].id}]", item[:quantity] %>
19
+ <%= text_field_tag "quantity[#{item[:sellable].id}]", item[:quantity] %>
20
20
  <% else -%>
21
21
  <%= item[:quantity] %>
22
22
  <% end -%>
23
23
  </td>
24
- <td><%= number_to_currency item[:quantity]*item[:variant].price %></td>
24
+ <td><%= number_to_currency item[:quantity]*item[:sellable].price %></td>
25
25
  <% if page == "cart" -%>
26
26
  <td>
27
- <%= link_to "Remove", piggybak.remove_item_url(item[:variant].id), :method => :delete %>
27
+ <%= link_to "Remove", piggybak.remove_item_url(item[:sellable].id), :method => :delete %>
28
28
  </td>
29
29
  <% end -%>
30
30
  </tr>
@@ -48,6 +48,15 @@
48
48
  <td>Shipping</td>
49
49
  <td id="shipping_total"></td>
50
50
  </tr>
51
+ <% Piggybak.config.line_item_types.each do |k, v| -%>
52
+ <% if v.has_key?(:display_in_cart) -%>
53
+ <tr id="<%= "#{k}_row" %>" style="display:none;">
54
+ <td colspan="<%= page == "cart" ? "3" : "2" %>"></td>
55
+ <td><%= v[:display_in_cart] %></td>
56
+ <td class="extra_totals" id="<%= k %>_total">$0.00</td>
57
+ </tr>
58
+ <% end -%>
59
+ <% end -%>
51
60
  <tr>
52
61
  <td colspan="<%= page == "cart" ? "3" : "2" %>"></td>
53
62
  <td>Total</td>
@@ -2,8 +2,16 @@ Thanks for your order!
2
2
 
3
3
  Items
4
4
 
5
- <% @order.line_items.each do |line_item| %>
6
- <%= line_item.variant.description %> x <%= line_item.quantity %> = <%= number_to_currency line_item.total %>
5
+ <% @order.line_items.sellables.each do |line_item| %>
6
+ <%= line_item.description %> x <%= line_item.quantity %> = <%= number_to_currency line_item.price %>
7
+ <% end -%>
8
+
9
+ <% @order.line_items.shipments.each do |line_item| %>
10
+ <%= line_item.description %> = <%= number_to_currency line_item.price %>
11
+ <% end -%>
12
+
13
+ <% @order.line_items.payments.each do |line_item| %>
14
+ <%= line_item.description %> = <%= number_to_currency line_item.price %>
7
15
  <% end -%>
8
16
 
9
17
  Total
@@ -5,12 +5,12 @@
5
5
  <th>Quantity</th>
6
6
  <th>Subtotal</th>
7
7
  </tr>
8
- <% order.line_items.each do |line_item| %>
8
+ <% order.line_items.sellables.each do |line_item| %>
9
9
  <tr>
10
10
  <td><%= line_item.description %></td>
11
- <td><%= number_to_currency line_item.price %></td>
11
+ <td><%= number_to_currency line_item.unit_price %></td>
12
12
  <td><%= line_item.quantity %></td>
13
- <td><%= number_to_currency line_item.total %></td>
13
+ <td><%= number_to_currency line_item.price %></td>
14
14
  </tr>
15
15
  <% end -%>
16
16
  <tr>
@@ -19,7 +19,7 @@
19
19
  <tr>
20
20
  <td colspan="2"></td>
21
21
  <td>Subtotal</td>
22
- <td><%= number_to_currency order.line_items.inject(0) { |subtotal, li| subtotal + li.total } %></td>
22
+ <td><%= number_to_currency order.line_items.sellables.inject(0) { |subtotal, li| subtotal + li.price } %></td>
23
23
  </tr>
24
24
  <tr>
25
25
  <td colspan="2"></td>
@@ -29,8 +29,17 @@
29
29
  <tr>
30
30
  <td colspan="2"></td>
31
31
  <td>Shipping</td>
32
- <td><%= number_to_currency order.shipments.inject(0) { |shipping, shipment| shipping + shipment.total } %></td>
32
+ <td><%= number_to_currency order.shipment_charge %></td>
33
+ </tr>
34
+ <% Piggybak.config.line_item_types.each do |k, v| -%>
35
+ <% if v.has_key?(:display_in_cart) && order.line_items.detect { |li| li.line_item_type == k.to_s } -%>
36
+ <tr>
37
+ <td colspan="2"></td>
38
+ <td><%= v[:display_in_cart] %></td>
39
+ <td class="extra_totals" id="<%= k %>_total"><%= number_to_currency order.line_items.detect { |li| li.line_item_type == k.to_s }.price %></td>
33
40
  </tr>
41
+ <% end -%>
42
+ <% end -%>
34
43
  <tr>
35
44
  <td colspan="2"></td>
36
45
  <td>Total</td>
@@ -4,16 +4,16 @@ _gaq.push(['_addTrans',
4
4
  '<%= store_name %>',
5
5
  '<%= @order.total %>',
6
6
  '<%= @order.tax_charge %>',
7
- '<%= @order.shipments.first.total %>',
7
+ '<%= @order.shipment_charge %>',
8
8
  '<%= @order.billing_address.city %>',
9
9
  '<%= @order.billing_address.state_display %>',
10
10
  '<%= @order.billing_address.country.name %>'
11
11
  ]);
12
12
 
13
- <% @order.line_items.each do |line_item| -%>
13
+ <% @order.line_items.sellables.each do |line_item| -%>
14
14
  _gaq.push(['_addItem',
15
15
  '<%= @order.id %>',
16
- '<%= line_item.variant.try(:sku) %>',
16
+ '<%= line_item.sellable.try(:sku) %>',
17
17
  '<%= line_item.description %>',
18
18
  '', // category or variation
19
19
  '<%= line_item.price %>', //unit price
@@ -3,16 +3,16 @@ Order: #<%= @order.id %>
3
3
  Email: <%= @order.email %>
4
4
  Phone: <%= @order.phone %>
5
5
 
6
- <% @order.line_items.each do |line_item| %>
7
- <%= line_item.quantity %> x <%= raw line_item.description %> (<%= number_to_currency line_item.total %>)
6
+ <% @order.line_items.sellables.each do |line_item| %>
7
+ <%= line_item.quantity %> x <%= raw line_item.description %> (<%= number_to_currency line_item.price %>)
8
8
  <% end -%>
9
9
 
10
- Subtotal: <%= number_to_currency @order.line_items.inject(0) { |subtotal, li| subtotal + li.total } %>
11
- Shipping & Handling: <%= number_to_currency @order.shipments.inject(0) { |shipping, shipment| shipping + shipment.total } %>
10
+ Subtotal: <%= number_to_currency @order.line_items.sellables.inject(0) { |subtotal, li| subtotal + li.price } %>
11
+ Shipping & Handling: <%= number_to_currency @order.line_items.shipments.inject(0) { |shipping, shipment| shipping + shipment.price } %>
12
12
  Tax: <%= number_to_currency @order.tax_charge %>
13
13
  Total: <%= number_to_currency @order.total %>
14
- Less Payment: <%= number_to_currency(@order.payments.inject(0) { |total, p| total + p.total if p.status == "paid" }) %>
15
- Adjustments: <%= number_to_currency(@order.adjustments.inject(0) { |total, adj| total + adj.total }) %>
14
+ Less Payment: <%= number_to_currency(@order.line_items.payments.inject(0) { |total, p| total + p.price if p.payment.status == "paid" }) %>
15
+ Adjustments: <%= number_to_currency(@order.line_items.adjustments.inject(0) { |total, adj| total + adj.price }) %>
16
16
  Balance Due: <%= number_to_currency @order.total_due %>
17
17
 
18
18
  Billing Information
@@ -6,7 +6,7 @@
6
6
  <% if @order.errors.any? -%>
7
7
  <div id="checkout_error">
8
8
  <b>You have errors with your submission:</b><br />
9
- <%= raw @order.errors.full_messages.join("<br />") %>
9
+ <%= raw @order.errors.full_messages.collect { |b| b.gsub(/^Line items payment/, 'Payment').gsub(/^Line items shipment shipping/, 'Shipping') }.join("<br />") %>
10
10
  </div>
11
11
  <% end -%>
12
12
  <div class="clear"></div>
@@ -50,59 +50,65 @@
50
50
  <div id="add_details">
51
51
  <div id="shipping">
52
52
  <h3>Shipping Option</h3>
53
- <%= f.fields_for :shipments, f.object.shipments.build do |shipment| %>
54
- <div class="item">
55
- <%= shipment.label :shipping_method_id %>
56
- <%= shipment.select :shipping_method_id, [] %>
57
- <div id="shipping_spinner" style="display:none;">
58
- <%= image_tag "ajax-loader.gif" %>
59
- </div>
60
- <div id="shipping_default" style="display:none;">
61
- Please enter a shipping address.
62
- </div>
63
- <div id="shipping_empty" style="display:none;">
64
- No shipping methods found.
65
- </div>
66
- </div>
53
+ <%= f.fields_for :line_items, @order.line_items.detect { |li| li.line_item_type == "shipment" } do |line_item_f| %>
54
+ <%= line_item_f.hidden_field :line_item_type, { :value => "shipment" } %>
55
+ <%= line_item_f.fields_for :shipment do |shipment| %>
56
+ <div class="item">
57
+ <%= shipment.label :shipping_method_id %>
58
+ <%= shipment.select :shipping_method_id, [] %>
59
+ <div id="shipping_spinner" style="display:none;">
60
+ <%= image_tag "ajax-loader.gif" %>
61
+ </div>
62
+ <div id="shipping_default" style="display:none;">
63
+ Please enter a shipping address.
64
+ </div>
65
+ <div id="shipping_empty" style="display:none;">
66
+ No shipping methods found.
67
+ </div>
68
+ </div>
69
+ <% end -%>
67
70
  <% end -%>
68
71
  </div>
69
72
  <div id="payment">
70
73
  <h3>Payment</h3>
71
- <%= f.fields_for :payments, f.object.payments.build do |payment| %>
72
- <div class="item">
73
- <%= payment.label :number %>
74
- <% if @order.errors.keys.include?("payments.number".to_sym) %>
75
- <span class="field_with_errors">
76
- <%= payment.text_field :number %>
77
- </span>
78
- <% else -%>
79
- <%= payment.text_field :number %>
80
- <% end -%>
81
- </div>
82
-
83
- <div class="item">
84
- <%= payment.label :verification_value %>
85
- <% if @order.errors.keys.include?("payments.verification_value".to_sym) %>
86
- <span class="field_with_errors">
87
- <%= payment.text_field :verification_value %>
88
- </span>
89
- <% else -%>
90
- <%= payment.text_field :verification_value %>
91
- <% end -%>
92
- </div>
93
-
94
- <div class="item">
95
- <%= payment.label :month %>
96
- <% if @order.errors.keys.include?("payments.verification_value".to_sym) %>
97
- <span class="field_with_errors">
98
- <%= payment.select :month, 1.upto(12).to_a %> /
99
- <%= payment.select :year, Time.now.year.upto(Time.now.year + 10).to_a %>
100
- </span>
101
- <% else -%>
102
- <%= payment.select :month, 1.upto(12).to_a %> /
103
- <%= payment.select :year, Time.now.year.upto(Time.now.year + 10).to_a %>
74
+ <%= f.fields_for :line_items, @order.line_items.detect { |li| li.line_item_type == "payment" } do |line_item_f| %>
75
+ <%= line_item_f.hidden_field :line_item_type, { :value => "payment" } %>
76
+ <%= line_item_f.fields_for :payment do |payment| %>
77
+ <div class="item">
78
+ <%= payment.label :number %>
79
+ <% if @order.errors.keys.include?("payments.number".to_sym) %>
80
+ <span class="field_with_errors">
81
+ <%= payment.text_field :number %>
82
+ </span>
83
+ <% else -%>
84
+ <%= payment.text_field :number %>
85
+ <% end -%>
86
+ </div>
87
+
88
+ <div class="item">
89
+ <%= payment.label :verification_value %>
90
+ <% if @order.errors.keys.include?("payments.verification_value".to_sym) %>
91
+ <span class="field_with_errors">
92
+ <%= payment.text_field :verification_value %>
93
+ </span>
94
+ <% else -%>
95
+ <%= payment.text_field :verification_value %>
96
+ <% end -%>
97
+ </div>
98
+
99
+ <div class="item">
100
+ <%= payment.label :month %>
101
+ <% if @order.errors.keys.include?("payments.verification_value".to_sym) %>
102
+ <span class="field_with_errors">
103
+ <%= payment.select :month, 1.upto(12).to_a %> /
104
+ <%= payment.select :year, Time.now.year.upto(Time.now.year + 10).to_a %>
105
+ </span>
106
+ <% else -%>
107
+ <%= payment.select :month, 1.upto(12).to_a %> /
108
+ <%= payment.select :year, Time.now.year.upto(Time.now.year + 10).to_a %>
109
+ <% end -%>
110
+ </div>
104
111
  <% end -%>
105
- </div>
106
112
  <% end -%>
107
113
  </div>
108
114
  <div id="submit">
@@ -8,8 +8,8 @@
8
8
  - else
9
9
  = form.text_field "state_id"
10
10
 
11
- - if type == "billing"
12
- = javascript_include_tag "piggybak.states"
13
-
14
11
  :javascript
15
12
  var geodata_lookup = "#{piggybak.orders_geodata_url}";
13
+
14
+ - if type == "billing"
15
+ = javascript_include_tag "piggybak.states"
@@ -3,32 +3,32 @@ N/A
3
3
  <% else -%>
4
4
  <table cellpadding="5" cellspacing="0">
5
5
  <tr>
6
- <td width="150">Subtotal</td>
7
- <td>$<%= "%.2f" % form.object.line_items.inject(0) { |subtotal, li| subtotal + li.total } %></td>
6
+ <td width="150">Subtotal (Sellables)</td>
7
+ <td><%= number_to_currency form.object.subtotal %></td>
8
8
  </tr>
9
9
  <tr>
10
10
  <td>Shipping</td>
11
- <td>$<%= "%.2f" % form.object.shipments.inject(0) { |shipping, shipment| shipping + shipment.total } %></td>
11
+ <td><%= number_to_currency form.object.shipment_charge %></td>
12
12
  </tr>
13
13
  <tr>
14
14
  <td>Tax</td>
15
- <td>$<%= "%.2f" % form.object.tax_charge %></td>
15
+ <td><%= number_to_currency form.object.tax_charge %></td>
16
16
  </tr>
17
17
  <tr>
18
- <td>Total</td>
19
- <td>$<%= "%.2f" % form.object.total %></td>
18
+ <td>Adjustments</td>
19
+ <td><%= number_to_currency form.object.adjustment_charge %></td>
20
20
  </tr>
21
21
  <tr>
22
- <td>Payments</td>
23
- <td>$<%= "%.2f" % form.object.payments.inject(0) { |total, payment| total + payment.total } %></td>
22
+ <td>Total</td>
23
+ <td><%= number_to_currency form.object.total %></td>
24
24
  </tr>
25
25
  <tr>
26
- <td>Adjustments</td>
27
- <td>$<%= "%.2f" % form.object.adjustments.inject(0) { |total, adj| total + adj.total.to_f } %></td>
26
+ <td>Payments</td>
27
+ <td><%= number_to_currency form.object.payment_charge %></td>
28
28
  </tr>
29
29
  <tr>
30
30
  <td>Balance Due</td>
31
- <td>$<%= "%.2f" % form.object.total_due %></td>
31
+ <td><%= number_to_currency form.object.total_due %></td>
32
32
  </tr>
33
33
  <tr>
34
34
  <td>Created at</td>
@@ -42,23 +42,11 @@ N/A
42
42
  <li><%= link_to "Send or Resend Email Confirmation", piggybak.email_order_url(form.object.id) %></li>
43
43
  <li><%= link_to "View as Text", piggybak.download_order_url(form.object.id) %></li>
44
44
  <% if form.object.total_due == 0.00 -%>
45
- <li><%= link_to "Cancel Order", piggybak.cancel_order_url(form.object.id) %> (This does not mark the payment gateway payments. This marks payments tied to ths order in this database as refunded, and marks the order as cancelled.)</li>
45
+ <li><%= link_to "Cancel Order", piggybak.cancel_order_url(form.object.id) %> (This does not refund payments.)</li>
46
46
  <% end -%>
47
47
  </ul>
48
48
  </td>
49
49
  </tr>
50
- <% else -%>
51
- <tr>
52
- <td valign="top">Actions</td>
53
- <td>
54
- <ul>
55
- <li>
56
- <%= link_to "Restore Cancel Order", piggybak.restore_order_url(form.object.id) %>
57
- (This marks order as un-cancelled.)
58
- </li>
59
- </ul>
60
- </td>
61
- </tr>
62
50
  <% end -%>
63
51
  </table>
64
52
  <% end -%>
@@ -0,0 +1,29 @@
1
+ - if form.object.new_record?
2
+ = form.select "line_item_type", Piggybak::LineItem.line_item_type_select, {}, :onchange => "toggle_line_item($(this));"
3
+ - else
4
+ = form.hidden_field "line_item_type"
5
+ = form.object.line_item_type
6
+
7
+ %script
8
+ var line_item_types=#{raw Piggybak.config.line_item_types.to_json};
9
+ var toggle_line_item = function(el) {
10
+ el.parent().parent().siblings('div').hide();
11
+ if(line_item_types[el.val()].fields === undefined) {
12
+ line_item_types[el.val()].fields = new Array();
13
+ }
14
+ $.each(line_item_types[el.val()].fields, function(a, b) {
15
+ el.parent().parent().siblings('.' + b + '_field').show();
16
+ if(line_item_types[el.val()].nested_attrs !== undefined) {
17
+ el.parent().parent().siblings('.' + b + '_field').find('> .controls,> .control-label').hide();
18
+ }
19
+ });
20
+ };
21
+ $.each($('.line_item_type_field select,.line_item_type_field input'), function(i, el) {
22
+ toggle_line_item($(el));
23
+ });
24
+ //Removing delete-ability of line_item_types that can't be destroyed
25
+ $.each($('.line_item_type_field input'), function(i, el) {
26
+ if(!line_item_types[$(el).val()].allow_destroy) {
27
+ $(el).parentsUntil('fieldset').parent().parent().find('.remove_nested_fields').remove();
28
+ }
29
+ });