stall 0.3.2 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +15 -21
  3. data/app/assets/javascripts/para/stall/inputs/variants-matrix/input.coffee +8 -1
  4. data/app/assets/javascripts/para/stall/inputs/variants-matrix/variant.coffee +9 -0
  5. data/app/assets/javascripts/stall.coffee +7 -1
  6. data/app/assets/javascripts/stall/add-to-cart-form.coffee +1 -4
  7. data/app/assets/javascripts/stall/products-filters.coffee +29 -0
  8. data/app/assets/stylesheets/para/stall.sass +5 -0
  9. data/app/assets/stylesheets/stall.sass +0 -0
  10. data/app/controllers/stall/checkout/steps_controller.rb +6 -5
  11. data/app/controllers/stall/checkout_base_controller.rb +14 -0
  12. data/app/controllers/stall/checkouts_controller.rb +7 -4
  13. data/app/controllers/stall/curated_product_lists_controller.rb +10 -0
  14. data/app/controllers/stall/line_items_controller.rb +1 -5
  15. data/app/controllers/stall/manufacturers_controller.rb +12 -0
  16. data/app/controllers/stall/omniauth_callbacks_controller.rb +49 -0
  17. data/app/controllers/stall/product_categories_controller.rb +13 -0
  18. data/app/controllers/stall/products_breadcrumbs.rb +16 -0
  19. data/app/controllers/stall/products_controller.rb +20 -0
  20. data/app/controllers/stall/products_search.rb +11 -0
  21. data/app/helpers/stall/customers_helper.rb +0 -10
  22. data/app/helpers/stall/omniauth_helper.rb +7 -0
  23. data/app/helpers/stall/prices_helper.rb +12 -0
  24. data/app/helpers/stall/products_filters_helper.rb +34 -0
  25. data/app/mailers/stall/customer_mailer.rb +4 -3
  26. data/app/models/curated_list_product.rb +3 -0
  27. data/app/models/curated_product_list.rb +3 -0
  28. data/app/models/image.rb +3 -0
  29. data/app/models/product_suggestion.rb +3 -0
  30. data/app/models/stall/models/curated_list_product.rb +15 -0
  31. data/app/models/stall/models/curated_product_list.rb +22 -0
  32. data/app/models/stall/models/customer.rb +5 -8
  33. data/app/models/stall/models/image.rb +21 -0
  34. data/app/models/stall/models/manufacturer.rb +4 -0
  35. data/app/models/stall/models/product.rb +30 -7
  36. data/app/models/stall/models/product_category.rb +5 -2
  37. data/app/models/stall/models/product_list.rb +1 -1
  38. data/app/models/stall/models/product_suggestion.rb +14 -0
  39. data/app/models/stall/models/shipment.rb +0 -2
  40. data/app/models/stall/models/user.rb +18 -0
  41. data/app/models/stall/models/user_omniauth_account.rb +13 -0
  42. data/app/models/stall/models/variant.rb +11 -11
  43. data/app/models/user.rb +3 -0
  44. data/app/models/user_omniauth_account.rb +3 -0
  45. data/app/services/stall/add_to_cart_service.rb +19 -4
  46. data/app/services/stall/available_stocks_service.rb +11 -0
  47. data/app/services/stall/cart_credit_note_creation_service.rb +4 -0
  48. data/app/services/stall/cart_payment_validation_service.rb +5 -3
  49. data/app/services/stall/credit_usage_service.rb +8 -2
  50. data/app/services/stall/omniauth_user_authentication_service.rb +48 -0
  51. data/app/services/stall/product_list_staleness_handling_service.rb +6 -3
  52. data/app/services/stall/products_search_service.rb +23 -0
  53. data/app/services/stall/shipping_notification_service.rb +1 -1
  54. data/app/views/admin/carts/_filters.html.haml +10 -4
  55. data/app/views/admin/carts/_form.html.haml +9 -9
  56. data/app/views/admin/manufacturers/_form.html.haml +7 -0
  57. data/app/views/admin/manufacturers/_table.html.haml +8 -0
  58. data/app/views/admin/product_categories/_form.html.haml +7 -0
  59. data/app/views/admin/products/_form.html.haml +23 -0
  60. data/app/views/admin/products/_table.html.haml +4 -2
  61. data/app/views/checkout/steps/_informations.html.haml +2 -2
  62. data/app/views/para/admin/resources/_variant_row.html.haml +9 -1
  63. data/app/views/para/admin/resources/_variant_row_header.html.haml +14 -0
  64. data/app/views/para/stall/inputs/_variant_select.html.haml +3 -3
  65. data/app/views/para/stall/inputs/_variants_matrix.html.haml +7 -16
  66. data/app/views/para/stall/inputs/shipping_notes/new.html.haml +22 -0
  67. data/app/views/para/stall/inputs/shipping_notes/sent.html.haml +11 -0
  68. data/app/views/stall/carts/_cart.html.haml +1 -1
  69. data/app/views/stall/credit_note_adjustments/_form.html.haml +1 -1
  70. data/app/views/stall/curated_product_lists/show.html.haml +8 -0
  71. data/app/views/stall/customers/_fields.html.haml +17 -5
  72. data/app/views/stall/customers/_sign_in.html.haml +22 -10
  73. data/app/views/stall/line_items/_form.html.haml +2 -3
  74. data/app/views/stall/manufacturers/show.html.haml +8 -0
  75. data/app/views/stall/product_categories/show.html.haml +8 -0
  76. data/app/views/stall/products/_filters.html.haml +4 -0
  77. data/app/views/stall/products/_list.html.haml +7 -0
  78. data/app/views/stall/products/_product.html.haml +4 -0
  79. data/app/views/stall/products/_product_details.html.haml +13 -0
  80. data/app/views/stall/products/filters/_category_filter.html.haml +2 -0
  81. data/app/views/stall/products/filters/_manufacturer_filter.html.haml +2 -0
  82. data/app/views/stall/products/filters/_price_filter.html.haml +2 -0
  83. data/app/views/stall/products/filters/_property_filter.html.haml +2 -0
  84. data/app/views/stall/products/index.html.haml +8 -0
  85. data/app/views/stall/products/show.html.haml +26 -0
  86. data/config/locales/stall.fr.yml +97 -11
  87. data/db/migrate/20170221094450_add_slug_to_stall_manufacturers.rb +5 -0
  88. data/db/migrate/20170303122616_create_stall_product_suggestions.rb +13 -0
  89. data/db/migrate/20170303151939_add_position_to_stall_manufacturers.rb +5 -0
  90. data/db/migrate/20170308162740_create_stall_curated_product_lists.rb +10 -0
  91. data/db/migrate/20170308163532_create_stall_curated_list_products.rb +14 -0
  92. data/db/migrate/20170317103740_create_stall_users.rb +28 -0
  93. data/db/migrate/20170317104332_create_stall_user_omniauth_accounts.rb +14 -0
  94. data/db/migrate/20170320133513_fix_curated_product_list_bad_foreign_key.rb +6 -0
  95. data/db/migrate/20170321104203_create_stall_images.rb +11 -0
  96. data/db/migrate/20170321112248_remove_image_attachment_to_stall_products.rb +5 -0
  97. data/db/migrate/20170411134756_add_stock_to_stall_variants.rb +5 -0
  98. data/lib/ext/ransack.rb +13 -0
  99. data/lib/generators/stall/install/templates/initializer.rb +50 -15
  100. data/lib/generators/stall/service/service_generator.rb +0 -4
  101. data/lib/generators/stall/view/view_generator.rb +10 -8
  102. data/lib/para/stall/inputs/variant_select_input.rb +11 -1
  103. data/lib/para/stall/inputs/variants_matrix_input.rb +12 -6
  104. data/lib/stall.rb +14 -0
  105. data/lib/stall/addressable.rb +2 -2
  106. data/lib/stall/addresses/copy_source_to_target.rb +7 -3
  107. data/lib/stall/addresses/prefill_target_from_source.rb +4 -2
  108. data/lib/stall/cart_helper.rb +3 -3
  109. data/lib/stall/carts_cleaner.rb +2 -2
  110. data/lib/stall/checkout/informations_checkout_step.rb +2 -2
  111. data/lib/stall/config.rb +29 -9
  112. data/lib/stall/engine.rb +28 -13
  113. data/lib/stall/omniauth_provider.rb +41 -0
  114. data/lib/stall/payable.rb +3 -1
  115. data/lib/stall/product_filters.rb +12 -0
  116. data/lib/stall/product_filters/base_filter.rb +43 -0
  117. data/lib/stall/product_filters/builder.rb +59 -0
  118. data/lib/stall/product_filters/category_filter.rb +28 -0
  119. data/lib/stall/product_filters/manufacturer_filter.rb +19 -0
  120. data/lib/stall/product_filters/price_filter.rb +39 -0
  121. data/lib/stall/product_filters/property_filter.rb +38 -0
  122. data/lib/stall/routes.rb +40 -0
  123. data/lib/stall/shipping/calculator.rb +3 -1
  124. data/lib/stall/version.rb +1 -1
  125. metadata +158 -7
  126. data/app/assets/stylesheets/stall/carts.css +0 -4
@@ -10,6 +10,10 @@ module Stall
10
10
  if cart.remainder? && !adjustment_exists?
11
11
  credit_note = create_credit_note!
12
12
  create_adjustment_for!(credit_note)
13
+
14
+ true
15
+ else
16
+ false
13
17
  end
14
18
  end
15
19
 
@@ -10,6 +10,10 @@ module Stall
10
10
  cart.payment.pay!
11
11
  send_payment_notification_emails!
12
12
  create_credit_notes!
13
+
14
+ # Always return true since errors should have raised if anything got
15
+ # wrong.
16
+ true
13
17
  end
14
18
 
15
19
  private
@@ -20,9 +24,7 @@ module Stall
20
24
  end
21
25
 
22
26
  def create_credit_notes!
23
- if cart.remainder?
24
- Stall.config.service_for(:cart_credit_note_creation).new(cart).call
25
- end
27
+ Stall.config.service_for(:cart_credit_note_creation).new(cart).call
26
28
  end
27
29
  end
28
30
  end
@@ -10,7 +10,8 @@ module Stall
10
10
  end
11
11
 
12
12
  def call
13
- raise CartAlreadyPaidError, "Cannot udpate credit note from paid cart"
13
+ ensure_cart_paid!('Cannot udpate credit note from paid cart')
14
+
14
15
  return false unless enough_credit?
15
16
 
16
17
  clean_credit_note_adjustments!
@@ -50,7 +51,8 @@ module Stall
50
51
  end
51
52
 
52
53
  def clean_credit_note_adjustments!
53
- raise CartAlreadyPaidError, "Cannot remove credit note from paid cart"
54
+ ensure_cart_paid!('Cannot remove credit note from paid cart')
55
+
54
56
  credit_note_adjustments.each do |adjustment|
55
57
  cart.adjustments.destroy(adjustment)
56
58
  end
@@ -102,5 +104,9 @@ module Stall
102
104
  CreditNoteAdjustment === adjustment
103
105
  end
104
106
  end
107
+
108
+ def ensure_cart_paid!(error_message)
109
+ raise(CartAlreadyPaidError, error_message) if cart.paid?
110
+ end
105
111
  end
106
112
  end
@@ -0,0 +1,48 @@
1
+ module Stall
2
+ class OmniauthUserAuthenticationService < Stall::BaseService
3
+ attr_reader :email, :auth
4
+
5
+ def initialize(email, auth)
6
+ @email = email
7
+ @auth = auth
8
+ end
9
+
10
+ def call
11
+ if existing_user
12
+ ensure_omniauth_account!(existing_user, auth)
13
+ existing_user
14
+ else
15
+ create_user_from_auth!
16
+ end
17
+ end
18
+
19
+ private
20
+
21
+ def ensure_omniauth_account(user, auth)
22
+ account = user.user_omniauth_accounts.find { |account| account.provider == auth.provider }
23
+ return account if account
24
+
25
+ user.user_omniauth_accounts.build(provider: auth.provider, uid: auth.uid)
26
+ end
27
+
28
+ def ensure_omniauth_account!(user, auth)
29
+ ensure_omniauth_account(user, auth)
30
+ user.save!
31
+ end
32
+
33
+ def existing_user
34
+ @existing_user ||= User.joins(:user_omniauth_accounts).where(
35
+ '(stall_user_omniauth_accounts.provider = ? AND stall_user_omniauth_accounts.uid = ?) OR stall_users.email = ?',
36
+ auth.provider, auth.uid, email
37
+ ).first
38
+ end
39
+
40
+ def create_user_from_auth!
41
+ User.create! do |user|
42
+ user.email = email
43
+ user.password = Devise.friendly_token
44
+ ensure_omniauth_account(user, auth)
45
+ end
46
+ end
47
+ end
48
+ end
@@ -15,7 +15,7 @@ module Stall
15
15
  def handle_line_items
16
16
  cart.line_items.each do |line_item|
17
17
  if stale?(line_item)
18
- cart.line_items.delete(line_item)
18
+ cart.line_items.delete(line_item)
19
19
  else
20
20
  handle_valid_line_item(line_item)
21
21
  end
@@ -26,8 +26,11 @@ module Stall
26
26
  # Override this method
27
27
  end
28
28
 
29
- def stale? line_item
30
- line_item.sellable.nil? || !line_item.sellable.published?
29
+ def stale?(line_item)
30
+ # The line item does not match a sellable (product deleted)
31
+ return true unless (sellable = line_item.sellable)
32
+ # The sellable is not published anymore
33
+ line_item.sellable.try(:published?) == false
31
34
  end
32
35
  end
33
36
  end
@@ -0,0 +1,23 @@
1
+ module Stall
2
+ class ProductsSearchService < Stall::BaseService
3
+ attr_reader :products, :params, :search
4
+ alias_method :form, :search
5
+
6
+ def initialize(products, params)
7
+ @products = products
8
+ @params = params
9
+ end
10
+
11
+ def call
12
+ @search = products.ransack(params[:search])
13
+ end
14
+
15
+ def search
16
+ @search || call
17
+ end
18
+
19
+ def records
20
+ search.result.distinct
21
+ end
22
+ end
23
+ end
@@ -9,8 +9,8 @@ module Stall
9
9
 
10
10
  def call
11
11
  if shipment.update(shipment_params)
12
- send_customer_email
13
12
  update_shipment
13
+ send_customer_email
14
14
 
15
15
  true
16
16
  else
@@ -1,17 +1,23 @@
1
1
  = search_form_for @q, builder: SimpleForm::FormBuilder, url: @component.path, html: { data: { :'filters-form' => true } } do |form|
2
2
  .row
3
- .col-md-3
3
+ .col-md-2
4
4
  = form.input_field :payment_paid_at_null, as: :selectize, collection: [{ text: t('activerecord.enums.payment.state.paid'), value: '0' }, { text: t('activerecord.enums.payment.state.pending'), value: '1' }], placeholder: @component.model.human_attribute_name(:payment)
5
5
 
6
- .col-md-3
6
+ .col-md-2
7
7
  = form.input_field :state_eq, as: :selectize, collection: DefaultCheckoutWizard.steps.map { |step| { text: t("activerecord.enums.cart.state.#{ step }"), value: step } }, placeholder: @component.model.human_attribute_name(:state)
8
8
 
9
- .col-md-4
9
+ .col-md-2
10
+ = form.input_field :payment_paid_at_gteq, as: :date, placeholder: t('para.stall.cart.filters.paid_after')
11
+
12
+ .col-md-2
13
+ = form.input_field :payment_paid_at_lteq, as: :date, placeholder: t('para.stall.cart.filters.paid_before')
14
+
15
+ .col-md-3
10
16
  .input-group
11
17
  %span.input-group-addon
12
18
  %i.fa.fa-search
13
19
 
14
20
  = form.input_field :reference_or_customer_email_cont, as: :string, placeholder: t('para.shared.search'), class: 'form-control'
15
21
 
16
- .col-md-2
22
+ .col-md-1
17
23
  = form.submit t('para.shared.search'), class: 'btn btn-default btn-block'
@@ -1,6 +1,6 @@
1
1
  = para_form_for(resource) do |form|
2
2
  = form.tabs do |tabs|
3
- = tabs.tab :informations do
3
+ = tabs.tab :informations, icon: 'info-circle' do
4
4
  = form.input :reference
5
5
  = form.input :total_price do
6
6
  .input-group
@@ -10,8 +10,8 @@
10
10
 
11
11
  = form.actions
12
12
 
13
- = tabs.tab :billing do
14
- = form.input :customer, :as => :nested_one
13
+ = tabs.tab :billing, icon: 'user' do
14
+ = form.input :customer, as: :nested_one
15
15
 
16
16
  = form.input :billing_address do
17
17
  .nested-one-field
@@ -20,8 +20,8 @@
20
20
 
21
21
  = form.actions
22
22
 
23
- = tabs.tab :shipping do
24
- = form.input :shipment, :as => :nested_one
23
+ = tabs.tab :shipping, icon: 'truck' do
24
+ = form.input :shipment, as: :nested_one
25
25
 
26
26
  = form.input :shipping_address do
27
27
  .nested-one-field
@@ -30,13 +30,13 @@
30
30
 
31
31
  = form.actions
32
32
 
33
- = tabs.tab :payment do
34
- = form.input :payment, :as => :nested_one
33
+ = tabs.tab :payment, icon: 'credit-card' do
34
+ = form.input :payment, as: :nested_one
35
35
 
36
36
  = form.actions
37
37
 
38
- = tabs.tab :line_items do
39
- = form.input :line_items, :as => :nested_many
38
+ = tabs.tab :line_items, icon: 'list' do
39
+ = form.input :line_items, as: :nested_many
40
40
 
41
41
  = form.actions
42
42
 
@@ -0,0 +1,7 @@
1
+ = para_form_for(resource) do |form|
2
+ = form.fieldset do
3
+ = form.input :name
4
+ = form.input :logo, as: :image
5
+ = form.input :products, as: :selectize
6
+
7
+ = form.actions
@@ -0,0 +1,8 @@
1
+ = resources_table(model: model, component: component) do |table|
2
+ = table.header do
3
+ = table.header_for(:name)
4
+ = table.header_for(:logo)
5
+
6
+ = table.rows(resources) do |resource|
7
+ = table.data_for(resource, :name)
8
+ = table.data_for(resource, :logo)
@@ -0,0 +1,7 @@
1
+ = para_form_for(resource) do |form|
2
+ = form.fieldset do
3
+ = form.input :name
4
+ = form.input :slug
5
+ = form.input :parent, as: :selectize
6
+
7
+ = form.actions
@@ -0,0 +1,23 @@
1
+ = para_form_for(resource) do |form|
2
+ = form.tabs do |tabs|
3
+ = tabs.tab :informations, icon: 'info-circle' do
4
+ = form.input :visible
5
+ = form.input :name
6
+ = form.input :slug, as: :string
7
+
8
+ = form.input :product_category, as: :selectize, collection: Para.components.product_categories.resources.leaves
9
+ = form.input :manufacturer, as: :selectize
10
+
11
+ = form.input :suggested_products, as: :selectize
12
+
13
+ = tabs.tab :images, icon: 'picture-o' do
14
+ = form.input :images, as: :nested_many
15
+
16
+ = tabs.tab :descriptions, icon: 'font' do
17
+ = form.input :description, as: :redactor
18
+ = form.input :product_details, as: :nested_many
19
+
20
+ = tabs.tab :variants, icon: 'list' do
21
+ = form.input :variants, as: :variants_matrix
22
+
23
+ = form.actions
@@ -1,12 +1,14 @@
1
1
  = resources_table(model: model, component: component) do |table|
2
2
  = table.header do
3
+ = table.header_for(:image)
3
4
  = table.header_for(:name)
4
- = table.header_for(:published)
5
+ = table.header_for(:visible)
5
6
  = table.header_for(:price, sort: :variants_price)
6
7
  = table.header_for(:product_category, sort: :product_category_name)
7
8
 
8
9
  = table.rows(resources) do |resource|
10
+ %td= image_tag(resource.image.url(:thumb)) if resource.image
9
11
  = table.data_for(resource, :name)
10
- = table.data_for(resource, :published)
12
+ = table.data_for(resource, :visible)
11
13
  = table.data_for(resource, :price)
12
14
  = table.data_for(resource, :product_category)
@@ -1,8 +1,8 @@
1
1
  = render partial: 'stall/checkout/steps/navigation', locals: { cart: cart, wizard: @wizard, step: @step }
2
2
 
3
3
  -# Display sign in form for users that are not signed in
4
- - unless stall_user_signed_in?
5
- - resource = Stall.config.default_user_model.new
4
+ - unless user_signed_in?
5
+ - resource = User.new
6
6
  = render partial: 'stall/customers/sign_in', locals: { resource: resource, resource_name: resource.model_name.element }
7
7
 
8
8
  %h1= t('stall.checkout.informations.title')
@@ -10,7 +10,7 @@
10
10
 
11
11
  - all_properties.each do |property_config|
12
12
  -# Hide all fields for new records
13
- %td{ class: ('hidden' unless form.object.persisted? && property_config.active?), data: { :'variants-matrix-variant-property' => property_config.property.id } }
13
+ %td{ class: ('hidden' unless property_config.active?), data: { :'variants-matrix-variant-property' => property_config.property.id } }
14
14
  = form.fields_for :variant_property_values, [property_config.variant_property_value_or_build_for(form.object)] do |fields|
15
15
  %span{ data: { :'property-name' => true } }
16
16
  = property_config.property_value_for(form.object).try(:name)
@@ -22,3 +22,11 @@
22
22
  = form.input_field :price, class: 'form-control'
23
23
  %span.input-group-addon
24
24
  = form.object.currency.symbol
25
+
26
+ - if Stall.config.manage_inventory
27
+ %td
28
+ = form.input_field :stock, class: 'form-control'
29
+
30
+ %td
31
+ %button.btn.btn-default.btn-shadow.hint--left{ type: 'button', :'aria-label' => t('para.stall.variants_matrix.apply_to_all'), data: { :'variants-matrix-apply-to-all' => true } }
32
+ = fa_icon 'sort-amount-asc'
@@ -0,0 +1,14 @@
1
+ %tr
2
+ %th{ data: { :'variants-matrix-variant-enabled-cell' => true } }
3
+ = t('para.stall.variants_matrix.enabled')
4
+
5
+ - properties.each do |variants_property_config|
6
+ %th{ data: { :'variants-matrix-variant-property-cell' => true } }
7
+ = variants_property_config.property.name
8
+
9
+ %th= t('para.stall.variants_matrix.price')
10
+
11
+ - if Stall.config.manage_inventory
12
+ %th= t('para.stall.variants_matrix.stock')
13
+
14
+ %th
@@ -8,7 +8,7 @@
8
8
  - else
9
9
  .variant-select-property{ data: { :'variant-select-property' => property_config.property.id } }
10
10
  .row
11
- .col-md-3
11
+ .variant-select-label-container{ class: variant_label_class }
12
12
  = label :property_config, property_config.property.id, property_config.property.name, class: 'variant-select-label'
13
- .col-md-9
14
- = select :property_config, property_config.property.id, options_for_select(property_config.available_options), { include_blank: true }, placeholder: t('para.stall.variant_select.property_placeholder'), class: 'variant-select-property-input', autocomplete: 'off', data: { selectize: true }
13
+ .variant-select-property-container{ class: variant_property_class }
14
+ = select :property_config, property_config.property.id, options_for_select(property_config.available_options), { include_blank: true }, placeholder: t('para.stall.variant_select.property_placeholder'), class: 'variant-select-property-input', autocomplete: 'off', data: { selectize: true, multi: false }
@@ -1,11 +1,10 @@
1
- .variants-matrix-input-container{ data: { :'variants-matrix-input' => true } }
1
+ .variants-matrix-input-container{ data: { :'variants-matrix-input' => true, :'allow-empty-variant' => allow_empty_variant } }
2
2
  = form.input :properties do
3
3
  .variants-matrix-properties-select{ data: { :'variants-matrix-properties-select' => true } }
4
4
  %p.help-block= t('para.stall.variants_matrix.choose_properties_to_build_variants')
5
5
 
6
6
  .dropdown
7
7
  %button.btn.btn-primary{ type: 'button', data: { toggle: 'dropdown' } }
8
- = fa_icon 'plus'
9
8
  = t('para.stall.variants_matrix.add_property')
10
9
  %span.caret
11
10
  .dropdown-menu.variants-matrix-property-selector
@@ -14,27 +13,19 @@
14
13
  = check_box :properties, :activated, { checked: variants_property_config.active? , autocomplete: 'off', data: { :'variants-matrix-property-selector-input' => true } }, variants_property_config.property.id
15
14
  = variants_property_config.property.name
16
15
 
17
- %ul.list-group
16
+ %ul.list-group.variants-matrix-properties-list
18
17
  - all_properties.each do |variants_property_config|
19
18
  %li.list-group-item{ class: ('hidden' unless variants_property_config.active?), data: { :'variants-matrix-property-id' => variants_property_config.property.id } }
20
- .row
21
- .col-md-3
22
- = label :variants_property_config, variants_property_config.property.id, variants_property_config.property.name
23
- .col-md-9
24
- = select :variants_property_config, variants_property_config.property.id, options_for_select(variants_property_config.options), {}, multiple: true, autocomplete: 'off', data: { :'variants-matrix-property-select' => variants_property_config.property.name }
19
+ .form-group
20
+ = label :variants_property_config, variants_property_config.property.id, variants_property_config.property.name, class: 'control-label'
21
+ = select :variants_property_config, variants_property_config.property.id, options_for_select(variants_property_config.options), {}, multiple: true, autocomplete: 'off', data: { :'variants-matrix-property-select' => variants_property_config.property.name }
25
22
 
26
23
  = form.input :variants do
27
24
  %table.table.table-hover
28
25
  %thead{ data: { :'variants-matrix-variants-table-header' => true } }
29
- %tr
30
- %th{ data: { :'variants-matrix-variant-enabled-cell' => true } }= t('para.stall.variants_matrix.enabled')
26
+ = render partial: find_partial_for(model, :variant_row_header), locals: { form: form, properties: properties }
31
27
 
32
- - properties.each do |variants_property_config|
33
- %th{ data: { :'variants-matrix-variant-property-cell' => true } }= variants_property_config.property.name
34
-
35
- %th= t('para.stall.variants_matrix.price')
36
-
37
- %tbody{ data: { :'variants-matrix-variants-container' => "#{ dom_identifier }" } }
28
+ %tbody{ data: { :'variants-matrix-variants-container' => dom_identifier } }
38
29
  = form.fields_for attribute_name, variants do |variant_fields|
39
30
  = render partial: find_partial_for(model, :variant_row), locals: { form: variant_fields }.merge(variant_row_locals)
40
31
 
@@ -0,0 +1,22 @@
1
+ = modal id: "shipment-modal-#{ @cart.id }", fade: false do |modal|
2
+ = modal.header do
3
+ = t('para.stall.shipping_note.create')
4
+
5
+ = simple_form_for @shipment, url: @component.relation_path(@cart, :shipping_note), method: :post, remote: true do |form|
6
+ = modal.body do
7
+ - if @shipment.notification_email_sent_at
8
+ .alert.alert-warning
9
+ = t('para.stall.shipping_note.notification_already_sent_at', date: l(@shipment.notification_email_sent_at)).html_safe
10
+
11
+ .well
12
+ = t('para.stall.shipping_note.help').html_safe
13
+
14
+ = form.input :shipping_method, as: :selectize
15
+ = form.input :tracking_code, hint: t('para.stall.shipping_note.tracking_code_help').html_safe
16
+
17
+ = modal.footer do
18
+ %button.btn.btn-default{ type: 'button', data: { dismiss: 'modal' } }
19
+ = t('stall.shared.cancel')
20
+
21
+ %button.btn.btn-primary{ type: 'submit' }
22
+ = t('stall.shared.send')