stall 0.3.2 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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')