stall 0.1.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +41 -3
- data/app/assets/javascripts/stall/add-to-cart-form.coffee +55 -3
- data/app/assets/javascripts/stall/addresses-fields.coffee +17 -0
- data/app/assets/javascripts/stall/remote-sign-in-form.coffee +55 -0
- data/app/assets/javascripts/stall.coffee +3 -1
- data/app/controllers/stall/application_controller.rb +1 -1
- data/app/controllers/stall/carts_controller.rb +1 -3
- data/app/controllers/stall/checkout/steps_controller.rb +18 -1
- data/app/helpers/stall/checkout_helper.rb +7 -8
- data/app/helpers/stall/customers_helper.rb +25 -0
- data/app/models/stall/models/cart.rb +2 -0
- data/app/models/stall/models/customer.rb +20 -0
- data/app/models/stall/models/product_list.rb +13 -0
- data/app/views/checkout/steps/_informations.html.haml +24 -35
- data/app/views/checkout/steps/_payment.html.haml +1 -45
- data/app/views/checkout/steps/_shipping_method.html.haml +0 -1
- data/app/views/stall/addresses/_fields.html.haml +16 -0
- data/app/views/stall/addresses/_nested_fields.html.haml +14 -0
- data/app/views/stall/carts/_cart.html.haml +45 -0
- data/app/views/stall/carts/show.html.haml +2 -2
- data/app/views/stall/customers/_fields.html.haml +32 -0
- data/app/views/stall/customers/_sign_in.html.haml +20 -0
- data/app/views/stall/line_items/_form.html.haml +2 -2
- data/app/views/stall/payments/_fields.html.haml +2 -0
- data/app/views/stall/shared/mailers/_cart.html.haml +31 -29
- data/app/views/stall/shipments/_fields.html.haml +2 -0
- data/config/locales/stall.fr.yml +35 -8
- data/lib/generators/stall/checkout/step/templates/step.rb.erb +9 -0
- data/lib/generators/stall/checkout/wizard/templates/wizard.rb.erb +1 -1
- data/lib/generators/stall/install/install_generator.rb +6 -0
- data/lib/generators/stall/install/templates/initializer.rb +10 -1
- data/lib/generators/stall/view/view_generator.rb +38 -0
- data/lib/stall/addressable.rb +2 -0
- data/lib/stall/addresses/copier_base.rb +24 -0
- data/lib/stall/addresses/copy_source_to_target.rb +45 -0
- data/lib/stall/addresses/prefill_target_from_source.rb +29 -0
- data/lib/stall/addresses.rb +9 -0
- data/lib/stall/cart_helper.rb +14 -1
- data/lib/stall/checkout/informations_checkout_step.rb +133 -14
- data/lib/stall/checkout/payment_checkout_step.rb +21 -1
- data/lib/stall/checkout/step.rb +22 -15
- data/lib/stall/checkout/step_form.rb +22 -8
- data/lib/stall/config.rb +17 -3
- data/lib/stall/engine.rb +6 -0
- data/lib/stall/payable.rb +9 -0
- data/lib/stall/payments/gateway.rb +16 -6
- data/lib/stall/payments/urls_config.rb +2 -2
- data/lib/stall/rails/routing_mapper.rb +4 -6
- data/lib/stall/routes.rb +4 -1
- data/lib/stall/sellable.rb +13 -3
- data/lib/stall/version.rb +1 -1
- data/lib/stall.rb +1 -0
- metadata +25 -6
- data/lib/stall/checkout/payment_method_checkout_step.rb +0 -9
- data/lib/stall/checkout/shipping_method_checkout_step.rb +0 -21
@@ -0,0 +1,32 @@
|
|
1
|
+
-# When stall a user is signed in, a customer autoatically exist and is assigned
|
2
|
+
-# to the cart, by default, we notify the visitor that he's signed in and will
|
3
|
+
-# order with that account, making customer and user related fields unnecessary
|
4
|
+
- if stall_user_signed_in?
|
5
|
+
.alert.alert-info
|
6
|
+
%i.fa.fa-info-circle
|
7
|
+
= t('stall.checkout.informations.signed_in_as', email: current_stall_user.email)
|
8
|
+
|
9
|
+
- else
|
10
|
+
-# The `#with_errors_from_user` helper ensures that user e-mail errors, like
|
11
|
+
-# format or uniqueness, are actually bubbled up to the customer e-mail field.
|
12
|
+
= form.fields_for :customer, with_errors_from_user(form.object.customer) do |customer_form|
|
13
|
+
= customer_form.input :email
|
14
|
+
|
15
|
+
= form.fields_for :customer do |customer_form|
|
16
|
+
= customer_form.fields_for :user, customer_form.object.user_or_default do |user_form|
|
17
|
+
%fieldset.collapse{ class: ('in' if params[:create_account] == '1'), data: { :'user-fields' => true } }
|
18
|
+
= user_form.input :password
|
19
|
+
= user_form.input :password_confirmation
|
20
|
+
|
21
|
+
%p.help-block
|
22
|
+
%label
|
23
|
+
-# This field allows the step to determine wether an account should be
|
24
|
+
-# created or not while creating the customer, allowing it to clean
|
25
|
+
-# user related fields if it's not needed.
|
26
|
+
-#
|
27
|
+
-# The `autocomplete="off"` clears the Firefox cache that autofills the
|
28
|
+
-# checked attribute and breaks the unerlying basic bootstrap collapse
|
29
|
+
-# behavior
|
30
|
+
= check_box_tag :create_account, '1', (params[:create_account] == '1'), class: 'collapsed', autocomplete: 'off', data: { target: '[data-user-fields]', toggle: 'collapse' }
|
31
|
+
= t('stall.checkout.informations.create_an_account')
|
32
|
+
%hr
|
@@ -0,0 +1,20 @@
|
|
1
|
+
.panel.panel-info
|
2
|
+
.panel-heading
|
3
|
+
%i.fa.fa-user
|
4
|
+
= t('stall.checkout.sign_in.already_have_an_account')
|
5
|
+
= link_to '#sign-in-form', data: { toggle: 'collapse' } do
|
6
|
+
= t('stall.checkout.sign_in.click_to_sign_in')
|
7
|
+
|
8
|
+
#sign-in-form.panel-body.collapse{ data: { :'sign-in-form' => true } }
|
9
|
+
%p.help-block
|
10
|
+
= t('stall.checkout.sign_in.sign_in_instructions', label: t('stall.checkout.sign_in.button_label'))
|
11
|
+
|
12
|
+
= simple_form_for resource, as: resource_name, url: session_path(resource_name), remote: true, html: { data: { :'stall-remote-sign-in-form' => true } } do |form|
|
13
|
+
.row
|
14
|
+
.col-md-6
|
15
|
+
= form.input :email
|
16
|
+
.col-md-6
|
17
|
+
= form.input :password
|
18
|
+
|
19
|
+
%button.btn.btn-primary{ type: 'submit', autocomplete: 'off', data: { :'sign-in-submit-btn' => true, :'loading-text' => t('stall.shared.sending') } }
|
20
|
+
= t('stall.checkout.sign_in.button_label')
|
@@ -1,4 +1,4 @@
|
|
1
|
-
= simple_form_for line_item, as: :line_item, url: cart_line_items_path(cart), remote: true, data: { :'add-to-cart-form' => true } do |form|
|
1
|
+
= simple_form_for line_item, as: :line_item, url: cart_line_items_path(cart), remote: true, data: { :'add-to-cart-form' => true, :'error-messages' => { choose: t('stall.line_items.errors.choose'), quantity: t('stall.line_items.errors.quantity') } } do |form|
|
2
2
|
= form.hidden_field :sellable_type
|
3
3
|
= form.hidden_field :sellable_id
|
4
4
|
|
@@ -6,7 +6,7 @@
|
|
6
6
|
= form.input_field :quantity, spinner: false, value: 1, class: 'form-group', data: { :'quantity-field' => true }
|
7
7
|
|
8
8
|
%span.input-group-btn
|
9
|
-
%button.btn.btn-primary{ type: 'submit',
|
9
|
+
%button.btn.btn-primary{ type: 'submit', data: { :'loading-text' => t('stall.shared.sending') } }
|
10
10
|
%i.fa.fa-shopping-cart
|
11
11
|
= t('stall.line_items.form.add_to_cart')
|
12
12
|
|
@@ -78,37 +78,39 @@
|
|
78
78
|
%td
|
79
79
|
%table
|
80
80
|
%tbody
|
81
|
-
|
82
|
-
%
|
83
|
-
%
|
81
|
+
- if cart.payment && cart.payment.payment_method
|
82
|
+
%tr
|
83
|
+
%td{ colspan: 2 }
|
84
|
+
%strong= Cart.human_attribute_name(:payment)
|
84
85
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
86
|
+
%tr
|
87
|
+
%td
|
88
|
+
= Payment.human_attribute_name(:payment_method)
|
89
|
+
%td
|
90
|
+
= cart.payment.payment_method.name
|
90
91
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
92
|
+
%tr
|
93
|
+
%td
|
94
|
+
= Payment.human_attribute_name(:state)
|
95
|
+
%td
|
96
|
+
- if cart.payment.paid?
|
97
|
+
= t("stall.carts.recap.paid_at", at: cart.payment.paid_at)
|
98
|
+
- else
|
99
|
+
= t("activerecord.enums.payment.state.#{ cart.payment.state }")
|
99
100
|
|
100
|
-
|
101
|
-
%
|
102
|
-
%
|
101
|
+
- if cart.shipment && cart.shipment.shipping_method
|
102
|
+
%tr
|
103
|
+
%td{ colspan: 2 }
|
104
|
+
%strong= Cart.human_attribute_name(:shipment)
|
103
105
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
106
|
+
%tr
|
107
|
+
%td
|
108
|
+
= Shipment.human_attribute_name(:shipping_method)
|
109
|
+
%td
|
110
|
+
= cart.shipment.shipping_method.name
|
109
111
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
112
|
+
%tr
|
113
|
+
%td
|
114
|
+
= Shipment.human_attribute_name(:state)
|
115
|
+
%td
|
116
|
+
= t("activerecord.enums.payment.state.#{ cart.shipment.state }")
|
data/config/locales/stall.fr.yml
CHANGED
@@ -2,14 +2,17 @@ fr:
|
|
2
2
|
stall:
|
3
3
|
shared:
|
4
4
|
close: "Fermer"
|
5
|
+
sending: "Envoi en cours ..."
|
5
6
|
|
6
7
|
carts:
|
7
8
|
formats:
|
8
9
|
name: "Commande n°%{ref}"
|
10
|
+
|
9
11
|
flashes:
|
10
12
|
update:
|
11
13
|
success: "Votre panier a bien été mis à jour."
|
12
14
|
error: "Votre panier n'a pu être mis à jour, merci de vérifier les champs."
|
15
|
+
|
13
16
|
recap:
|
14
17
|
order_ref: "Commande n°%{ref}"
|
15
18
|
ordered_at: "Passée le %{at}"
|
@@ -32,20 +35,28 @@ fr:
|
|
32
35
|
add_error:
|
33
36
|
title: "Votre produit n'a pu être ajouté"
|
34
37
|
description: "Merci de vérifier que vous avez bien rempli la quantité avant d'ajouter le produit au panier."
|
38
|
+
errors:
|
39
|
+
choose: "Merci de choisir un produit afin de l'ajouter au panier"
|
40
|
+
quantity: "Merci de choisir une quantité à ajouter au panier"
|
35
41
|
|
36
42
|
checkout:
|
37
43
|
shared:
|
38
|
-
not_checkoutable: "
|
44
|
+
not_checkoutable: "Le panier a expiré, celui-ci a probablement déjà été payé."
|
39
45
|
informations:
|
40
46
|
title: "Vos informations"
|
41
|
-
validate: "Valider
|
47
|
+
validate: "Valider la commande et passer au paiement"
|
42
48
|
error: "Vos informations n'ont pu être enregistrées, merci de vérifier les champs"
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
+
signed_in_as: "Vous êtes actuellement connectés en tant que %{email}"
|
50
|
+
create_an_account: "Me créer un compte"
|
51
|
+
accept_the: "J'accepte les "
|
52
|
+
sign_in:
|
53
|
+
already_have_an_account: "J'ai déjà un compte :"
|
54
|
+
click_to_sign_in: "Cliquez-ici pour vous connecter"
|
55
|
+
sign_in_instructions: |
|
56
|
+
Renseigez dans les champs suivant vos identifiants de connexion puis
|
57
|
+
cliquez sur le bouton "%{label}"
|
58
|
+
button_label: "Me connecter"
|
59
|
+
|
49
60
|
payment:
|
50
61
|
title: "Paiement"
|
51
62
|
error: |
|
@@ -91,6 +102,7 @@ fr:
|
|
91
102
|
state:
|
92
103
|
pending: "En attente"
|
93
104
|
shipped: "Payé"
|
105
|
+
|
94
106
|
models:
|
95
107
|
line_item: "Produit"
|
96
108
|
customer: "Client"
|
@@ -98,6 +110,7 @@ fr:
|
|
98
110
|
cart: "Panier"
|
99
111
|
shipment: "Livraison"
|
100
112
|
payment: "Paiement"
|
113
|
+
|
101
114
|
attributes:
|
102
115
|
line_item:
|
103
116
|
sellable: "Produit source"
|
@@ -129,6 +142,7 @@ fr:
|
|
129
142
|
customer: "Client"
|
130
143
|
created_at: "Date"
|
131
144
|
line_items: "Produits"
|
145
|
+
use_another_address_for_billing: "Utiliser une autre adresse pour la facturation"
|
132
146
|
cart:
|
133
147
|
state: "Étape du panier"
|
134
148
|
total_price: "Montant total"
|
@@ -136,6 +150,7 @@ fr:
|
|
136
150
|
shipment: "Livraison"
|
137
151
|
shipping_address: "Adresse de livraison"
|
138
152
|
billing_address: "Adresse de facturation"
|
153
|
+
terms: "Conditions générales de vente"
|
139
154
|
shipment:
|
140
155
|
price: "Prix"
|
141
156
|
eot_price: "Prix HT"
|
@@ -149,3 +164,15 @@ fr:
|
|
149
164
|
paid_at: "Payé le"
|
150
165
|
transaction_id: "Numéro de transaction"
|
151
166
|
state: "État"
|
167
|
+
|
168
|
+
simple_form:
|
169
|
+
placeholders:
|
170
|
+
address:
|
171
|
+
first_name: "Votre prénom"
|
172
|
+
last_name: "Votre nom"
|
173
|
+
address: "Numéro et rue"
|
174
|
+
address_details: "Autres informations : bâtiment, escalier, interphone etc."
|
175
|
+
country: "Votre pays"
|
176
|
+
zip: "Votre code postal"
|
177
|
+
city: "Votre ville"
|
178
|
+
phone: "Votre numéro de téléphone (portable / fixe)"
|
@@ -24,4 +24,13 @@ class <%= class_name %> < Stall::Checkout::Step
|
|
24
24
|
# def skip?
|
25
25
|
# false
|
26
26
|
# end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
# Process `params` here, defaults to assigning the cart with `cart_params`
|
31
|
+
# (params[:cart]) to the cart, running the step validations
|
32
|
+
#
|
33
|
+
def cart_params
|
34
|
+
params.require(:cart).permit({})
|
35
|
+
end
|
27
36
|
end
|
@@ -13,5 +13,11 @@ module Stall
|
|
13
13
|
def copy_default_checkout_wizard
|
14
14
|
generate 'stall:checkout:wizard', 'default'
|
15
15
|
end
|
16
|
+
|
17
|
+
def mount_engine_in_routes
|
18
|
+
say "Mounting Stall engine in routes"
|
19
|
+
gsub_file 'config/routes.rb', /mount_stall.+\n/, ''
|
20
|
+
route "mount_stall '/'"
|
21
|
+
end
|
16
22
|
end
|
17
23
|
end
|
@@ -56,7 +56,7 @@ Stall.configure do |config|
|
|
56
56
|
# that you create your line items, carts and orders with the right currency
|
57
57
|
# set.
|
58
58
|
#
|
59
|
-
#
|
59
|
+
# config.default_currency = 'EUR'
|
60
60
|
|
61
61
|
# Default app domain use for building URLs in payment gateway forms and in
|
62
62
|
# e-mails.
|
@@ -75,6 +75,15 @@ Stall.configure do |config|
|
|
75
75
|
# A default one is generated on stall's installation and can be found in your
|
76
76
|
# app at : lib/default_checkout_wizard.rb
|
77
77
|
#
|
78
|
+
# Note :
|
79
|
+
#
|
80
|
+
# If you do not autoload files in your app's lib folder, please require your
|
81
|
+
# checkout wizard with the following command here
|
82
|
+
#
|
83
|
+
# require 'default_checkout_wizard'
|
84
|
+
#
|
85
|
+
#
|
86
|
+
#
|
78
87
|
# config.default_checkout_wizard = 'DefaultCheckoutWizard'
|
79
88
|
|
80
89
|
# Default line items weight when added to cart and no weight is found on
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module Stall
|
2
|
+
class ViewGenerator < ::Rails::Generators::Base
|
3
|
+
class ViewNotFound < StandardError; end
|
4
|
+
|
5
|
+
VIEWS_DIR = File.expand_path('../../../../../app/views', __FILE__)
|
6
|
+
source_root VIEWS_DIR
|
7
|
+
|
8
|
+
argument :file_paths, type: :array, required: true
|
9
|
+
|
10
|
+
def copy_view_template
|
11
|
+
paths = file_paths.map do |file_path|
|
12
|
+
source_path = source_path_for(file_path)
|
13
|
+
raise ViewNotFound, "Could not find any stall view for #{ file_path }" unless File.exist?(source_path)
|
14
|
+
target_path = "app/views/#{ file_path_with_ext_for(file_path) }"
|
15
|
+
|
16
|
+
[source_path, target_path]
|
17
|
+
end
|
18
|
+
|
19
|
+
paths.each do |source_path, target_path|
|
20
|
+
template(source_path, target_path)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def source_path_for(file_path)
|
27
|
+
File.join(VIEWS_DIR, file_path_with_ext_for(file_path))
|
28
|
+
end
|
29
|
+
|
30
|
+
def file_path_with_ext_for(file_path)
|
31
|
+
if file_path.match(/\.html\.haml\z/)
|
32
|
+
file_path
|
33
|
+
else
|
34
|
+
"#{ file_path }.html.haml"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/stall/addressable.rb
CHANGED
@@ -0,0 +1,24 @@
|
|
1
|
+
module Stall
|
2
|
+
module Addresses
|
3
|
+
class CopierBase
|
4
|
+
attr_reader :source, :target
|
5
|
+
|
6
|
+
def initialize(source, target)
|
7
|
+
@source = source
|
8
|
+
@target = target
|
9
|
+
end
|
10
|
+
|
11
|
+
def copy
|
12
|
+
fail NotImplementedError
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def duplicate_attributes(model)
|
18
|
+
model.attributes.dup.tap do |attributes|
|
19
|
+
attributes.delete('id')
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# Allows copying
|
2
|
+
module Stall
|
3
|
+
module Addresses
|
4
|
+
class CopySourceToTarget < Stall::Addresses::CopierBase
|
5
|
+
def copy!
|
6
|
+
copy
|
7
|
+
target.save!
|
8
|
+
end
|
9
|
+
|
10
|
+
def copy
|
11
|
+
copy_shipping_address
|
12
|
+
copy_billing_address
|
13
|
+
end
|
14
|
+
|
15
|
+
private
|
16
|
+
|
17
|
+
def copy_shipping_address
|
18
|
+
# Update or create target's shipping address with source's shipping
|
19
|
+
# address attributes
|
20
|
+
if target.shipping_address
|
21
|
+
target.shipping_address.assign_attributes(duplicate_attributes(source.shipping_address))
|
22
|
+
else
|
23
|
+
target.build_shipping_address(duplicate_attributes(source.shipping_address))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
def copy_billing_address
|
28
|
+
# If the source uses the same address for shipping and billing, we
|
29
|
+
# reproduce this behavior ont the target
|
30
|
+
if source.shipping_address == source.billing_address
|
31
|
+
shipping_ownership = target.address_ownership_for(:shipping)
|
32
|
+
target.mark_address_ownership_as_billing(shipping_ownership)
|
33
|
+
# If the source has a separate billing address, we update or create the
|
34
|
+
# target's billing address with the source's one attributes
|
35
|
+
else
|
36
|
+
if target.billing_address
|
37
|
+
target.billing_address.assign_attributes(duplicate_attributes(source.billing_address))
|
38
|
+
else
|
39
|
+
target.build_billing_address(duplicate_attributes(source.billing_address))
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Stall
|
2
|
+
module Addresses
|
3
|
+
class PrefillTargetFromSource < Stall::Addresses::CopierBase
|
4
|
+
def copy
|
5
|
+
prefill_shipping_address
|
6
|
+
prefill_billing_address
|
7
|
+
end
|
8
|
+
|
9
|
+
private
|
10
|
+
|
11
|
+
def prefill_shipping_address
|
12
|
+
if source.shipping_address && !target.shipping_address
|
13
|
+
target.build_shipping_address(duplicate_attributes(source.shipping_address))
|
14
|
+
elsif !target.shipping_address
|
15
|
+
target.build_shipping_address
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def prefill_billing_address
|
20
|
+
if source.billing_address && !target.billing_address
|
21
|
+
target.build_billing_address(duplicate_attributes(source.billing_address))
|
22
|
+
elsif !target.billing_address || target.billing_address == target.shipping_address
|
23
|
+
target.address_ownership_for(:shipping).billing = false
|
24
|
+
target.build_billing_address
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/stall/cart_helper.rb
CHANGED
@@ -3,8 +3,10 @@ module Stall
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
included do
|
6
|
+
include Stall::CustomersHelper
|
7
|
+
|
6
8
|
if respond_to?(:helper_method)
|
7
|
-
helper_method :current_cart, :current_cart_key
|
9
|
+
helper_method :current_cart, :current_cart_key, :current_customer
|
8
10
|
end
|
9
11
|
|
10
12
|
if respond_to?(:after_action)
|
@@ -16,6 +18,16 @@ module Stall
|
|
16
18
|
RequestStore.store[cart_key] ||= load_current_cart
|
17
19
|
end
|
18
20
|
|
21
|
+
def current_customer
|
22
|
+
@current_customer ||= if stall_user_signed_in?
|
23
|
+
if (customer = current_stall_user.customer)
|
24
|
+
customer
|
25
|
+
else
|
26
|
+
current_stall_user.create_customer(email: current_stall_user.email)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
19
31
|
protected
|
20
32
|
|
21
33
|
def current_cart_key
|
@@ -35,6 +47,7 @@ module Stall
|
|
35
47
|
|
36
48
|
def prepare_cart(cart)
|
37
49
|
cart.tap do |cart|
|
50
|
+
cart.customer = current_customer if current_customer
|
38
51
|
# Keep track of potential customer locale switching to allow e-mailing
|
39
52
|
# him in his last used locale
|
40
53
|
cart.customer.locale = I18n.locale if cart.customer
|