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
@@ -0,0 +1,14 @@
1
+ class CreateStallCuratedListProducts < ActiveRecord::Migration
2
+ def change
3
+ create_table :stall_curated_list_products do |t|
4
+ t.references :product, index: true
5
+ t.references :curated_product_list
6
+ t.integer :position, default: 0
7
+
8
+ t.timestamps null: false
9
+ end
10
+
11
+ add_foreign_key :stall_curated_list_products, :stall_products, column: :product_id
12
+ add_foreign_key :stall_curated_list_products, :stall_products, column: :curated_product_list_id
13
+ end
14
+ end
@@ -0,0 +1,28 @@
1
+ class CreateStallUsers < ActiveRecord::Migration
2
+ def change
3
+ create_table :stall_users do |t|
4
+ ## Database authenticatable
5
+ t.string :email, null: false, default: ""
6
+ t.string :encrypted_password, null: false, default: ""
7
+
8
+ ## Recoverable
9
+ t.string :reset_password_token
10
+ t.datetime :reset_password_sent_at
11
+
12
+ ## Rememberable
13
+ t.datetime :remember_created_at
14
+
15
+ ## Trackable
16
+ t.integer :sign_in_count, default: 0, null: false
17
+ t.datetime :current_sign_in_at
18
+ t.datetime :last_sign_in_at
19
+ t.inet :current_sign_in_ip
20
+ t.inet :last_sign_in_ip
21
+
22
+ t.timestamps null: false
23
+ end
24
+
25
+ add_index :stall_users, :email, unique: true
26
+ add_index :stall_users, :reset_password_token, unique: true
27
+ end
28
+ end
@@ -0,0 +1,14 @@
1
+ class CreateStallUserOmniauthAccounts < ActiveRecord::Migration
2
+ def change
3
+ create_table :stall_user_omniauth_accounts do |t|
4
+ t.references :user, index: true
5
+ t.string :provider
6
+ t.string :uid
7
+ t.jsonb :scopes
8
+
9
+ t.timestamps null: false
10
+ end
11
+
12
+ add_foreign_key :stall_user_omniauth_accounts, :stall_users, column: 'user_id'
13
+ end
14
+ end
@@ -0,0 +1,6 @@
1
+ class FixCuratedProductListBadForeignKey < ActiveRecord::Migration
2
+ def change
3
+ remove_foreign_key :stall_curated_list_products, column: :curated_product_list_id
4
+ add_foreign_key :stall_curated_list_products, :stall_curated_product_lists, column: :curated_product_list_id
5
+ end
6
+ end
@@ -0,0 +1,11 @@
1
+ class CreateStallImages < ActiveRecord::Migration
2
+ def change
3
+ create_table :stall_images do |t|
4
+ t.integer :position, default: 0
5
+ t.references :imageable, polymorphic: true, index: true
6
+ t.attachment :file
7
+
8
+ t.timestamps null: false
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,5 @@
1
+ class RemoveImageAttachmentToStallProducts < ActiveRecord::Migration
2
+ def change
3
+ remove_attachment :stall_products, :image
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class AddStockToStallVariants < ActiveRecord::Migration
2
+ def change
3
+ add_column :stall_variants, :stock, :integer, default: 0
4
+ end
5
+ end
@@ -0,0 +1,13 @@
1
+ module Stall
2
+ module Ransack
3
+ def self.configure
4
+ ::Ransack.configure do |config|
5
+ config.add_predicate 'between_cents',
6
+ arel_predicate: 'between',
7
+ formatter: proc { |v| Range.new(*v.split(',').map { |s| (s.to_i * 100) }) },
8
+ validator: proc { |v| v.present? },
9
+ type: :string
10
+ end
11
+ end
12
+ end
13
+ end
@@ -25,20 +25,6 @@ Stall.configure do |config|
25
25
  #
26
26
  # config.sender_email = ENV['STALL_SENDER_EMAIL']
27
27
 
28
- # Set the customer associated user model used by the shop to bind user
29
- # accounts to.
30
- #
31
- # This model should have an e-mail, password and password_confirmation
32
- # fields.
33
- #
34
- # config.default_user_model_name = 'User'
35
-
36
- # A method available in all controllers to fetch the current signed in user
37
- # in your app. It should return a user model if the visitor is signed in, and
38
- # nil if it's unsigned.
39
- #
40
- # config.default_user_helper_method = :current_user
41
-
42
28
  # Global default VAT rate, can be overrided by products
43
29
  #
44
30
  # config.vat_rate = BigDecimal.new('20.0')
@@ -47,17 +33,57 @@ Stall.configure do |config|
47
33
  #
48
34
  # config.prices_precision = 2
49
35
 
36
+ # User omniauth providers that will be allowed for customers to authenticate
37
+ # with.
38
+ #
39
+ # For each activated integration, you need to add the app id and secret key
40
+ # environment variables.
41
+ #
42
+ # Example :
43
+ #
44
+ # For Facebook, add the FACEBOOK_APP_ID and FACEBOOK_SECRET_KEY environment
45
+ # variables.
46
+ #
47
+ # If you prefer, you can pass the app id and secret key to the
48
+ # config.omniauth_provider options.
49
+ #
50
+ # Example :
51
+ #
52
+ # config.omniauth_provider :facebook, app_id: '000000', secret_key; 'xxxxxx'
53
+ #
54
+ # Note that Facebook and Google omniauth integrations are included by default,
55
+ # and you can remove them as you want, but if you want to add a new provider,
56
+ # you'll have to include the `omniauth-<provider_name>` gem in your app's
57
+ # Gemfile to make it work.
58
+ #
59
+ # config.omniauth_provider :facebook
60
+ # config.omniauth_provider :google_oauth2, display_name: 'Google', icon: 'google'
61
+
62
+ # Configure `devise_for :user` call, if you need to customize some
63
+ # controllers behavior.
64
+ #
65
+ # config.devise_for_user_config = {
66
+ # controllers: { omniauth_callbacks: 'stall/omniauth_callbacks' }
67
+ # }
68
+
50
69
  # Default engine's controllers ancestor class
51
70
  #
52
71
  # config.application_controller_ancestor = '::ApplicationController'
53
72
 
54
- # Set a layout to use in the checkouts controllers
73
+ # Set a layout to use across all stall controllers
55
74
  #
56
75
  # The default is set to nil, which will make the controllers inherit from the
57
76
  # layout of the controller set in `config.application_controller_ancestor`
58
77
  #
59
78
  # config.default_layout = nil
60
79
 
80
+ # Set a layout to use in the checkouts controllers
81
+ #
82
+ # The default is set to nil, which will make it inherit from the
83
+ # `default_checkout` config behavior defined above.
84
+ #
85
+ # config.checkout_layout = nil
86
+
61
87
  # Defines the parent mailer for the Stall customer and admin mailers
62
88
  #
63
89
  # If commented out, ActionMailer::Base will be used
@@ -72,6 +98,15 @@ Stall.configure do |config|
72
98
  #
73
99
  # config.default_currency = 'EUR'
74
100
 
101
+ # Define if inventory levels should be managed through variants stocks.
102
+ #
103
+ # It defaults to `false`, allowing customers to order any quantity of products
104
+ # at the same time, but can be set to true, which would allow managing
105
+ # stocks for every variants and add inventory levels handling when adding
106
+ # to cart and on payment.
107
+ #
108
+ # config.manage_inventory = false
109
+
75
110
  # Default app domain use for building URLs in payment gateway forms and in
76
111
  # e-mails.
77
112
  #
@@ -11,10 +11,6 @@ module Stall
11
11
  end
12
12
 
13
13
  def post_template_message
14
- puts "\n" +
15
- "Service class generated. Please add the service to the " +
16
- "`config.services` hash in your config/initializers/stall.rb file\n\n"
17
-
18
14
  return if @services_folder_existed
19
15
 
20
16
  puts " * Warning : app/services folder was just created, \n" +
@@ -37,16 +37,18 @@ module Stall
37
37
  return @file_path_with_ext if @file_path_with_ext
38
38
  @file_path += '.html.haml' unless file_path.match(/\.html\.haml\z/)
39
39
 
40
- if File.exist?(source_file_for(file_path))
41
- @file_path_with_ext = file_path
42
- return @file_path_with_ext
43
- end
44
-
45
40
  partial_path = [File.dirname(file_path), File.basename(file_path)].join('/_')
46
41
 
47
- if File.exist?(source_file_for(partial_path))
48
- @file_path_with_ext = partial_path
49
- return @file_path_with_ext
42
+ stall_file_path = ['stall', file_path].join('/')
43
+ stall_partial_path = ['stall', partial_path].join('/')
44
+
45
+ paths = [file_path, partial_path, stall_file_path, stall_partial_path]
46
+
47
+ paths.each do |path|
48
+ if File.exist?(source_path = source_file_for(path))
49
+ @file_path_with_ext = path
50
+ return @file_path_with_ext
51
+ end
50
52
  end
51
53
 
52
54
  raise ViewNotFound, "No Stall view was found for #{ file_path } !"
@@ -14,7 +14,9 @@ module Para
14
14
  foreign_key: foreign_key,
15
15
  properties: properties,
16
16
  variants_data: variants_data,
17
- price_selector: price_selector
17
+ price_selector: price_selector,
18
+ variant_label_class: variant_label_class,
19
+ variant_property_class: variant_property_class
18
20
  }
19
21
  end
20
22
 
@@ -73,6 +75,14 @@ module Para
73
75
  end
74
76
  end
75
77
  end
78
+
79
+ def variant_label_class
80
+ options.fetch(:variant_label_class, 'col-md-3')
81
+ end
82
+
83
+ def variant_property_class
84
+ options.fetch(:variant_property_class, 'col-md-9')
85
+ end
76
86
  end
77
87
  end
78
88
  end
@@ -12,6 +12,8 @@ module Para
12
12
  def input(wrapper_options = nil)
13
13
  ensure_target_relation_present!
14
14
 
15
+ ensure_empty_variant_if_needed
16
+
15
17
  template.render partial: 'para/stall/inputs/variants_matrix', locals: {
16
18
  form: @builder,
17
19
  model: model,
@@ -19,9 +21,9 @@ module Para
19
21
  all_properties: all_properties,
20
22
  properties: properties,
21
23
  variants: variants,
22
- require_all_properties: require_all_properties,
23
24
  dom_identifier: dom_identifier,
24
- variant_row_locals: variant_row_locals
25
+ variant_row_locals: variant_row_locals,
26
+ allow_empty_variant: allow_empty_variant
25
27
  }
26
28
  end
27
29
 
@@ -45,10 +47,6 @@ module Para
45
47
  @variants ||= unsorted_variants.sort_by(&method(:variant_sort_method))
46
48
  end
47
49
 
48
- def require_all_properties
49
- options[:require_all_properties] || false
50
- end
51
-
52
50
  def dom_identifier
53
51
  @dom_identifier ||= [
54
52
  model.model_name.element,
@@ -66,6 +64,14 @@ module Para
66
64
  dom_identifier: dom_identifier
67
65
  }
68
66
  end
67
+
68
+ def allow_empty_variant
69
+ @allow_empty_variant ||= options.fetch(:allow_empty_variant, true)
70
+ end
71
+
72
+ def ensure_empty_variant_if_needed
73
+ object.variants.build if object.variants.empty? && allow_empty_variant
74
+ end
69
75
  end
70
76
  end
71
77
  end
@@ -7,7 +7,16 @@ require 'simple_form'
7
7
  require 'country_select'
8
8
  require 'cocoon'
9
9
  require 'deep_merge/rails_compat'
10
+ require 'friendly_id'
10
11
  require 'para'
12
+ require 'ransack'
13
+
14
+ require 'devise'
15
+ require 'omniauth'
16
+ require 'omniauth-facebook'
17
+ require 'omniauth-google-oauth2'
18
+
19
+ require 'ext/ransack'
11
20
 
12
21
  require 'stall/rails/routing_mapper'
13
22
  require 'stall/rails/currency_helper'
@@ -28,6 +37,11 @@ module Stall
28
37
  autoload :DefaultCurrencyManager
29
38
  autoload :ReferenceManager
30
39
  autoload :TotalPricesManager
40
+ autoload :ProductFilters
41
+ autoload :OmniauthProvider
42
+
43
+ autoload :ProductsSearch
44
+ autoload :ProductsBreadcrumbs
31
45
 
32
46
  autoload :Checkout
33
47
  autoload :Shipping
@@ -28,7 +28,7 @@ module Stall
28
28
  end
29
29
 
30
30
  def billing_address?
31
- billing_address.persisted? && billing_address.billing?
31
+ billing_address.try(:persisted?) && billing_address.billing?
32
32
  end
33
33
 
34
34
  # Allow shipping address to fall back to billing address when not filled
@@ -38,7 +38,7 @@ module Stall
38
38
  end
39
39
 
40
40
  def shipping_address?
41
- shipping_address.persisted? && shipping_address.billing?
41
+ shipping_address.try(:persisted?) && shipping_address.shipping?
42
42
  end
43
43
  end
44
44
  end
@@ -17,10 +17,14 @@ module Stall
17
17
  # Update or create target address with source attributes
18
18
  #
19
19
  def copy_address(type)
20
- address = target.send(:"#{ type }_address") || target.send(:"build_#{ type }_address")
20
+ address = if target.send(:"#{ type }_address?")
21
+ target.send(:"#{ type }_address")
22
+ else
23
+ target.send(:"build_#{ type }_address")
24
+ end
21
25
 
22
- if (source_address = source.send(:"#{ type }_address"))
23
- attributes = duplicate_attributes(source_address)
26
+ if source.send(:"#{ type }_address?")
27
+ attributes = duplicate_attributes(source.send(:"#{ type }_address"))
24
28
  address.assign_attributes(attributes)
25
29
  else
26
30
  address.try(:mark_for_destruction)
@@ -9,8 +9,10 @@ module Stall
9
9
  private
10
10
 
11
11
  def prefill_address(type)
12
- if source.send("#{ type }_address") && !target.send("#{ type }_address")
13
- attributes = duplicate_attributes(source.send("#{ type }_address"))
12
+ source_address = source.send("#{ type }_address")
13
+
14
+ if source_address && !target.send("#{ type }_address")
15
+ attributes = duplicate_attributes(source_address)
14
16
  target.send("build_#{ type }_address", attributes)
15
17
  elsif !target.send("#{ type }_address")
16
18
  target.send("build_#{ type }_address")
@@ -19,11 +19,11 @@ module Stall
19
19
  end
20
20
 
21
21
  def current_customer
22
- @current_customer ||= if stall_user_signed_in?
23
- if (customer = current_stall_user.customer)
22
+ @current_customer ||= if user_signed_in?
23
+ if (customer = current_user.customer)
24
24
  customer
25
25
  else
26
- current_stall_user.create_customer(email: current_stall_user.email)
26
+ current_user.create_customer(email: current_user.email)
27
27
  end
28
28
  end
29
29
  end
@@ -22,7 +22,7 @@ module Stall
22
22
  carts = cart_model.empty.older_than(Stall.config.empty_carts_expires_after.ago)
23
23
 
24
24
  log "Cleaning #{ carts.count } empty carts ..."
25
- carts.delete_all
25
+ carts.destroy_all
26
26
  log "Done."
27
27
  end
28
28
 
@@ -32,7 +32,7 @@ module Stall
32
32
  #
33
33
  # Note : The given cart model should implement the `.unpaid` method
34
34
  def clean_aborted_carts
35
- carts = cart_model.aborted(before: Stall.config.aborted_carts_expires_after.ago)
35
+ carts = cart_model.aborted
36
36
 
37
37
  log "Cleaning #{ carts.count } aborted carts ..."
38
38
  carts.destroy_all
@@ -107,7 +107,7 @@ module Stall
107
107
 
108
108
  # Remove user from customer to avoid automatic validation of the user
109
109
  # if no user should be saved with the customer
110
- unless stall_user_signed_in? || cart.customer.try(:user).try(:persisted?) ||
110
+ unless user_signed_in? || cart.customer.try(:user).try(:persisted?) ||
111
111
  !cart.customer
112
112
  then
113
113
  cart.customer.user = nil
@@ -120,7 +120,7 @@ module Stall
120
120
  def prepare_addresses_attributes
121
121
  unless use_another_address_for_billing?
122
122
  cart_params.delete(:billing_address_attributes)
123
- cart.billing_address.try(:mark_for_destruction)
123
+ cart.billing_address.try(:mark_for_destruction) if cart.billing_address?
124
124
  end
125
125
  end
126
126