solidus_core 2.1.1 → 2.2.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of solidus_core might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/Rakefile +0 -1
- data/app/assets/config/solidus_core_manifest.js +1 -0
- data/app/assets/javascripts/spree.js.erb +72 -0
- data/app/helpers/spree/store_helper.rb +5 -0
- data/app/jobs/spree/promotion_code_batch_job.rb +24 -0
- data/app/mailers/spree/promotion_code_batch_mailer.rb +13 -0
- data/app/models/concerns/spree/calculated_adjustments.rb +1 -1
- data/app/models/concerns/spree/ordered_property_value_list.rb +2 -2
- data/app/models/concerns/spree/user_address_book.rb +4 -4
- data/app/models/concerns/spree/user_methods.rb +7 -0
- data/app/models/concerns/spree/user_payment_source.rb +12 -5
- data/app/models/spree/address.rb +14 -3
- data/app/models/spree/adjustment.rb +13 -1
- data/app/models/spree/app_configuration.rb +0 -19
- data/app/models/spree/base.rb +2 -0
- data/app/models/spree/credit_card.rb +34 -43
- data/app/models/spree/gateway/bogus.rb +1 -1
- data/app/models/spree/gateway.rb +6 -4
- data/app/models/spree/inventory_unit.rb +3 -2
- data/app/models/spree/order/checkout.rb +187 -273
- data/app/models/spree/order.rb +137 -71
- data/app/models/spree/order_contents.rb +1 -1
- data/app/models/spree/order_inventory.rb +11 -11
- data/app/models/spree/order_promotion.rb +2 -0
- data/app/models/spree/order_update_attributes.rb +1 -8
- data/app/models/spree/order_updater.rb +67 -63
- data/app/models/spree/payment.rb +0 -1
- data/app/models/spree/payment_create.rb +27 -7
- data/app/models/spree/payment_method/store_credit.rb +3 -3
- data/app/models/spree/payment_method.rb +4 -1
- data/app/models/spree/payment_source.rb +45 -0
- data/app/models/spree/product/scopes.rb +24 -24
- data/app/models/spree/product.rb +4 -4
- data/app/models/spree/promotion.rb +2 -0
- data/app/models/spree/promotion_code/batch_builder.rb +63 -0
- data/app/models/spree/promotion_code.rb +1 -0
- data/app/models/spree/promotion_code_batch.rb +25 -0
- data/app/models/spree/promotion_handler/cart.rb +2 -2
- data/app/models/spree/promotion_handler/coupon.rb +1 -2
- data/app/models/spree/promotion_handler/free_shipping.rb +32 -21
- data/app/models/spree/promotion_handler/page.rb +1 -1
- data/app/models/spree/reimbursement.rb +1 -1
- data/app/models/spree/return_authorization.rb +0 -28
- data/app/models/spree/return_item.rb +1 -1
- data/app/models/spree/shipment.rb +4 -4
- data/app/models/spree/shipping_method.rb +2 -2
- data/app/models/spree/shipping_rate.rb +1 -1
- data/app/models/spree/stock/availability_validator.rb +16 -17
- data/app/models/spree/stock/coordinator.rb +3 -3
- data/app/models/spree/stock/package.rb +1 -1
- data/app/models/spree/stock/quantifier.rb +5 -4
- data/app/models/spree/stock_location.rb +2 -2
- data/app/models/spree/store.rb +2 -2
- data/app/models/spree/store_credit.rb +1 -1
- data/app/models/spree/tax/tax_helpers.rb +3 -3
- data/app/models/spree/tax_rate.rb +7 -1
- data/app/models/spree/taxonomy.rb +1 -1
- data/app/models/spree/variant/scopes.rb +5 -5
- data/app/models/spree/variant/vat_price_generator.rb +8 -5
- data/app/models/spree/variant.rb +1 -0
- data/app/models/spree/wallet/add_payment_sources_to_wallet.rb +19 -10
- data/app/models/spree/wallet/default_payment_builder.rb +6 -6
- data/app/models/spree/wallet.rb +71 -0
- data/app/models/spree/wallet_payment_source.rb +17 -0
- data/app/models/spree/zone.rb +1 -1
- data/app/views/spree/carton_mailer/shipped_email.text.erb +1 -1
- data/app/views/spree/promotion_code_batch_mailer/promotion_code_batch_errored.text.erb +2 -0
- data/app/views/spree/promotion_code_batch_mailer/promotion_code_batch_finished.text.erb +2 -0
- data/app/views/spree/reimbursement_mailer/reimbursement_email.html.erb +0 -7
- data/app/views/spree/reimbursement_mailer/reimbursement_email.text.erb +0 -5
- data/app/views/spree/shared/_error_messages.html.erb +1 -1
- data/app/views/spree/shipment_mailer/shipped_email.html.erb +1 -1
- data/config/initializers/assets.rb +1 -1
- data/config/initializers/friendly_id.rb +1 -1
- data/config/locales/en.yml +50 -12
- data/db/default/spree/store_credit.rb +2 -1
- data/db/migrate/20130826062534_add_depth_to_spree_taxons.rb +4 -6
- data/db/migrate/20160420044191_create_spree_wallet_payment_sources.rb +23 -0
- data/db/migrate/20160420181916_migrate_credit_cards_to_wallet_payment_sources.rb +26 -0
- data/db/migrate/20161017102621_create_spree_promotion_code_batch.rb +36 -0
- data/db/migrate/20161129035810_add_index_to_spree_payments_number.rb +5 -0
- data/db/migrate/20170223235001_remove_spree_store_credits_column.rb +5 -0
- data/lib/generators/spree/dummy/templates/rails/application.rb +1 -1
- data/lib/generators/spree/dummy/templates/rails/test.rb +1 -1
- data/lib/generators/spree/install/install_generator.rb +6 -5
- data/lib/spree/core/controller_helpers/payment_parameters.rb +54 -0
- data/lib/spree/core/engine.rb +6 -9
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/core.rb +0 -1
- data/lib/spree/money.rb +18 -0
- data/lib/spree/permission_sets/default_customer.rb +1 -1
- data/lib/spree/permitted_attributes.rb +1 -1
- data/lib/spree/testing_support/authorization_helpers.rb +1 -0
- data/lib/spree/testing_support/capybara_ext.rb +13 -0
- data/lib/spree/testing_support/factories/order_factory.rb +5 -1
- data/lib/spree/testing_support/factories/payment_factory.rb +1 -1
- data/lib/spree/testing_support/factories/shipment_factory.rb +0 -1
- data/solidus_core.gemspec +3 -3
- data/spec/jobs/promotion_code_batch_job_spec.rb +65 -0
- data/spec/lib/calculated_adjustments_spec.rb +105 -1
- data/spec/lib/spree/core/testing_support/factories/order_factory_spec.rb +4 -1
- data/spec/lib/spree/core/testing_support/factories/payment_factory_spec.rb +8 -0
- data/spec/lib/spree/money_spec.rb +32 -0
- data/spec/lib/spree/permission_sets/default_customer_spec.rb +20 -0
- data/spec/mailers/promotion_code_batch_mailer_spec.rb +45 -0
- data/spec/models/spree/credit_card_spec.rb +86 -86
- data/spec/models/spree/gateway_spec.rb +3 -1
- data/spec/models/spree/inventory_unit_spec.rb +12 -4
- data/spec/models/spree/order/checkout_spec.rb +11 -32
- data/spec/models/spree/order/tax_spec.rb +2 -2
- data/spec/models/spree/order_contents_spec.rb +24 -1
- data/spec/models/spree/order_inventory_spec.rb +130 -83
- data/spec/models/spree/order_spec.rb +15 -117
- data/spec/models/spree/order_update_attributes_spec.rb +1 -44
- data/spec/models/spree/order_updater_spec.rb +10 -13
- data/spec/models/spree/payment_create_spec.rb +5 -1
- data/spec/models/spree/payment_method_spec.rb +16 -0
- data/spec/models/spree/payment_spec.rb +14 -8
- data/spec/models/spree/promotion_code/batch_builder_spec.rb +61 -0
- data/spec/models/spree/promotion_code_batch_spec.rb +58 -0
- data/spec/models/spree/promotion_code_spec.rb +4 -0
- data/spec/models/spree/promotion_spec.rb +3 -6
- data/spec/models/spree/return_authorization_spec.rb +0 -59
- data/spec/models/spree/shipment_spec.rb +4 -4
- data/spec/models/spree/stock/availability_validator_spec.rb +64 -9
- data/spec/models/spree/tax/item_adjuster_spec.rb +1 -2
- data/spec/models/spree/unit_cancel_spec.rb +0 -85
- data/spec/models/spree/user_spec.rb +3 -1
- data/spec/models/spree/variant/vat_price_generator_spec.rb +8 -2
- data/spec/models/spree/variant_spec.rb +16 -4
- data/spec/models/spree/wallet_payment_source_spec.rb +46 -0
- data/spec/models/spree/wallet_spec.rb +128 -0
- data/spec/support/concerns/payment_source.rb +64 -0
- metadata +51 -25
- data/app/assets/javascripts/spree.js.coffee.erb +0 -64
- data/app/models/spree/promotion_builder.rb +0 -55
- data/app/models/spree/promotion_code/code_builder.rb +0 -62
- data/config/initializers/premailer_assets.rb +0 -1
- data/lib/spree/core/unreturned_item_charger.rb +0 -106
- data/lib/tasks/exchanges.rake +0 -47
- data/spec/lib/spree/core/unreturned_item_charger_spec.rb +0 -126
- data/spec/lib/tasks/exchanges_spec.rb +0 -220
- data/spec/models/spree/promotion_builder_spec.rb +0 -120
- data/spec/models/spree/promotion_code/code_builder_spec.rb +0 -77
@@ -2,24 +2,9 @@ module Spree
|
|
2
2
|
module Stock
|
3
3
|
class AvailabilityValidator < ActiveModel::Validator
|
4
4
|
def validate(line_item)
|
5
|
-
|
6
|
-
|
7
|
-
if units_by_shipment.blank?
|
8
|
-
ensure_in_stock(line_item, line_item.quantity)
|
5
|
+
if is_valid?(line_item)
|
6
|
+
true
|
9
7
|
else
|
10
|
-
units_by_shipment.each do |shipment, inventory_units|
|
11
|
-
ensure_in_stock(line_item, inventory_units.size, shipment.stock_location)
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
line_item.errors[:quantity].empty?
|
16
|
-
end
|
17
|
-
|
18
|
-
private
|
19
|
-
|
20
|
-
def ensure_in_stock(line_item, quantity, stock_location = nil)
|
21
|
-
quantifier = Stock::Quantifier.new(line_item.variant, stock_location)
|
22
|
-
unless quantifier.can_supply?(quantity)
|
23
8
|
variant = line_item.variant
|
24
9
|
display_name = variant.name.to_s
|
25
10
|
display_name += %{ (#{variant.options_text})} unless variant.options_text.blank?
|
@@ -28,6 +13,20 @@ module Spree
|
|
28
13
|
:selected_quantity_not_available,
|
29
14
|
item: display_name.inspect
|
30
15
|
)
|
16
|
+
false
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
def is_valid?(line_item)
|
23
|
+
if line_item.inventory_units.empty?
|
24
|
+
Stock::Quantifier.new(line_item.variant).can_supply?(line_item.quantity)
|
25
|
+
else
|
26
|
+
quantity_by_stock_location_id = line_item.inventory_units.pending.joins(:shipment).group(:stock_location_id).count
|
27
|
+
quantity_by_stock_location_id.all? do |stock_location_id, quantity|
|
28
|
+
Stock::Quantifier.new(line_item.variant, stock_location_id).can_supply?(quantity)
|
29
|
+
end
|
31
30
|
end
|
32
31
|
end
|
33
32
|
end
|
@@ -80,10 +80,10 @@ module Spree
|
|
80
80
|
# minimum required ActiveRecord objects.
|
81
81
|
def stock_location_variant_ids
|
82
82
|
# associate the variant ids we're interested in with stock location ids
|
83
|
-
location_variant_ids = StockItem.
|
83
|
+
location_variant_ids = Spree::StockItem.
|
84
84
|
where(variant_id: unallocated_variant_ids).
|
85
85
|
joins(:stock_location).
|
86
|
-
merge(StockLocation.active).
|
86
|
+
merge(Spree::StockLocation.active).
|
87
87
|
pluck(:stock_location_id, :variant_id)
|
88
88
|
|
89
89
|
# load activerecord objects for the stock location ids and turn them
|
@@ -92,7 +92,7 @@ module Spree
|
|
92
92
|
# <stock location id> => <stock location>,
|
93
93
|
# ...,
|
94
94
|
# }
|
95
|
-
location_lookup = StockLocation.
|
95
|
+
location_lookup = Spree::StockLocation.
|
96
96
|
where(id: location_variant_ids.map(&:first).uniq).
|
97
97
|
map { |l| [l.id, l] }.
|
98
98
|
to_h
|
@@ -101,7 +101,7 @@ module Spree
|
|
101
101
|
# @return [Array<Spree::ShippingCategory>] the shipping categories of the
|
102
102
|
# variants in this package
|
103
103
|
def shipping_categories
|
104
|
-
ShippingCategory.where(id: shipping_category_ids)
|
104
|
+
Spree::ShippingCategory.where(id: shipping_category_ids)
|
105
105
|
end
|
106
106
|
|
107
107
|
# @return [ActiveRecord::Relation] the [Spree::ShippingMethod]s available
|
@@ -3,15 +3,16 @@ module Spree
|
|
3
3
|
class Quantifier
|
4
4
|
attr_reader :stock_items
|
5
5
|
|
6
|
+
# @param [Variant] variant The variant to check inventory for.
|
7
|
+
# @param [StockLocation, Integer] stock_location The stock_location to check inventory in. If unspecified it will check inventory in all available StockLocations
|
6
8
|
def initialize(variant, stock_location = nil)
|
7
9
|
@variant = variant
|
8
|
-
|
10
|
+
@stock_items = Spree::StockItem.where(variant_id: variant)
|
9
11
|
if stock_location
|
10
|
-
|
12
|
+
@stock_items.where!(stock_location: stock_location)
|
11
13
|
else
|
12
|
-
|
14
|
+
@stock_items.joins!(:stock_location).merge!(Spree::StockLocation.active)
|
13
15
|
end
|
14
|
-
@stock_items = Spree::StockItem.joins(:stock_location).where(where_args)
|
15
16
|
end
|
16
17
|
|
17
18
|
# Returns the total number of inventory units on hand for the variant.
|
@@ -110,12 +110,12 @@ module Spree
|
|
110
110
|
private
|
111
111
|
|
112
112
|
def create_stock_items
|
113
|
-
Variant.find_each { |variant| propagate_variant(variant) }
|
113
|
+
Spree::Variant.find_each { |variant| propagate_variant(variant) }
|
114
114
|
end
|
115
115
|
|
116
116
|
def ensure_one_default
|
117
117
|
if default
|
118
|
-
StockLocation.where(default: true).where.not(id: id).each do |stock_location|
|
118
|
+
Spree::StockLocation.where(default: true).where.not(id: id).each do |stock_location|
|
119
119
|
stock_location.default = false
|
120
120
|
stock_location.save!
|
121
121
|
end
|
data/app/models/spree/store.rb
CHANGED
@@ -39,8 +39,8 @@ module Spree
|
|
39
39
|
|
40
40
|
def ensure_default_exists_and_is_unique
|
41
41
|
if default
|
42
|
-
Store.where.not(id: id).update_all(default: false)
|
43
|
-
elsif Store.where(default: true).count == 0
|
42
|
+
Spree::Store.where.not(id: id).update_all(default: false)
|
43
|
+
elsif Spree::Store.where(default: true).count == 0
|
44
44
|
self.default = true
|
45
45
|
end
|
46
46
|
end
|
@@ -17,9 +17,9 @@ module Spree
|
|
17
17
|
#
|
18
18
|
# For further discussion, see https://github.com/spree/spree/issues/4397 and https://github.com/spree/spree/issues/4327.
|
19
19
|
def applicable_rates(order)
|
20
|
-
|
20
|
+
order_zone_tax_category_ids = rates_for_order(order).map(&:tax_category_id)
|
21
21
|
default_rates_with_unmatched_tax_category = rates_for_default_zone.to_a.delete_if do |default_rate|
|
22
|
-
|
22
|
+
order_zone_tax_category_ids.include?(default_rate.tax_category_id)
|
23
23
|
end
|
24
24
|
|
25
25
|
(rates_for_order(order) + default_rates_with_unmatched_tax_category).uniq
|
@@ -38,7 +38,7 @@ module Spree
|
|
38
38
|
end
|
39
39
|
|
40
40
|
def rates_for_item(item)
|
41
|
-
applicable_rates(item.order).select { |rate| rate.
|
41
|
+
applicable_rates(item.order).select { |rate| rate.tax_category_id == item.tax_category_id }
|
42
42
|
end
|
43
43
|
end
|
44
44
|
end
|
@@ -62,7 +62,13 @@ module Spree
|
|
62
62
|
# Under no circumstances should negative adjustments be applied for the Spanish tax rates.
|
63
63
|
#
|
64
64
|
# Those rates should never come into play at all and only the French rates should apply.
|
65
|
-
scope :for_zone, ->(zone)
|
65
|
+
scope :for_zone, ->(zone) do
|
66
|
+
if zone
|
67
|
+
where(zone_id: Spree::Zone.with_shared_members(zone).pluck(:id))
|
68
|
+
else
|
69
|
+
none
|
70
|
+
end
|
71
|
+
end
|
66
72
|
scope :included_in_price, -> { where(included_in_price: true) }
|
67
73
|
|
68
74
|
# Creates necessary tax adjustments for the order.
|
@@ -2,7 +2,7 @@ module Spree
|
|
2
2
|
class Variant < Spree::Base
|
3
3
|
# FIXME: WARNING tested only under sqlite and postgresql
|
4
4
|
scope :descend_by_popularity, -> {
|
5
|
-
order("COALESCE((SELECT COUNT(*) FROM #{LineItem.quoted_table_name} GROUP BY #{LineItem.quoted_table_name}.variant_id HAVING #{LineItem.quoted_table_name}.variant_id = #{Variant.quoted_table_name}.id), 0) DESC")
|
5
|
+
order("COALESCE((SELECT COUNT(*) FROM #{Spree::LineItem.quoted_table_name} GROUP BY #{Spree::LineItem.quoted_table_name}.variant_id HAVING #{Spree::LineItem.quoted_table_name}.variant_id = #{Spree::Variant.quoted_table_name}.id), 0) DESC")
|
6
6
|
}
|
7
7
|
|
8
8
|
class << self
|
@@ -12,7 +12,7 @@ module Spree
|
|
12
12
|
#
|
13
13
|
# product.variants_including_master.has_option(OptionType.find_by(name: 'shoe-size'), OptionValue.find_by(name: '8'))
|
14
14
|
def has_option(option_type, *option_values)
|
15
|
-
option_types = OptionType.table_name
|
15
|
+
option_types = Spree::OptionType.table_name
|
16
16
|
|
17
17
|
option_type_conditions = case option_type
|
18
18
|
when OptionType then { "#{option_types}.name" => option_type.name }
|
@@ -24,9 +24,9 @@ module Spree
|
|
24
24
|
|
25
25
|
option_values.each do |option_value|
|
26
26
|
option_value_conditions = case option_value
|
27
|
-
when OptionValue then { "#{OptionValue.table_name}.name" => option_value.name }
|
28
|
-
when String then { "#{OptionValue.table_name}.name" => option_value }
|
29
|
-
else { "#{OptionValue.table_name}.id" => option_value }
|
27
|
+
when OptionValue then { "#{Spree::OptionValue.table_name}.name" => option_value.name }
|
28
|
+
when String then { "#{Spree::OptionValue.table_name}.name" => option_value }
|
29
|
+
else { "#{Spree::OptionValue.table_name}.id" => option_value }
|
30
30
|
end
|
31
31
|
relation = relation.where(option_value_conditions)
|
32
32
|
end
|
@@ -28,10 +28,7 @@ module Spree
|
|
28
28
|
# Don't re-create the default price
|
29
29
|
next if variant.default_price && variant.default_price.country_iso == country_iso
|
30
30
|
|
31
|
-
foreign_price = variant.
|
32
|
-
country_iso: country_iso,
|
33
|
-
currency: variant.default_price.currency,
|
34
|
-
)
|
31
|
+
foreign_price = find_or_initialize_price_by(country_iso, variant.default_price.currency)
|
35
32
|
|
36
33
|
foreign_price.amount = variant.default_price.net_amount * (1 + vat_for_country_iso(country_iso))
|
37
34
|
end
|
@@ -39,6 +36,12 @@ module Spree
|
|
39
36
|
|
40
37
|
private
|
41
38
|
|
39
|
+
def find_or_initialize_price_by(country_iso, currency)
|
40
|
+
variant.prices.detect do |price|
|
41
|
+
price.country_iso == country_iso && price.currency == currency
|
42
|
+
end || variant.prices.build(country_iso: country_iso, currency: currency)
|
43
|
+
end
|
44
|
+
|
42
45
|
# nil is added to the array so we always have an export price.
|
43
46
|
def country_isos_requiring_price
|
44
47
|
return [nil] unless variant.tax_category
|
@@ -51,7 +54,7 @@ module Spree
|
|
51
54
|
end
|
52
55
|
|
53
56
|
def variant_vat_rates
|
54
|
-
@variant_vat_rates ||= variant.tax_category.tax_rates.
|
57
|
+
@variant_vat_rates ||= variant.tax_category.tax_rates.included_in_price
|
55
58
|
end
|
56
59
|
end
|
57
60
|
end
|
data/app/models/spree/variant.rb
CHANGED
@@ -7,19 +7,28 @@ class Spree::Wallet::AddPaymentSourcesToWallet
|
|
7
7
|
end
|
8
8
|
|
9
9
|
# This is called after an order transistions to complete and should save the
|
10
|
-
# order's payment source
|
10
|
+
# order's payment source in the user's "wallet" for future use.
|
11
11
|
#
|
12
12
|
# @return [void]
|
13
13
|
def add_to_wallet
|
14
|
-
if !order.
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
14
|
+
if !order.temporary_payment_source && order.user
|
15
|
+
# select valid sources
|
16
|
+
payments = order.payments.valid
|
17
|
+
sources = payments.map(&:source).
|
18
|
+
uniq.
|
19
|
+
compact.
|
20
|
+
select { |p| p.try(:reusable?) }
|
21
|
+
|
22
|
+
# add valid sources to wallet and optionally set a default
|
23
|
+
if sources.any?
|
24
|
+
# arbitrarily sort by id for picking a default
|
25
|
+
wallet_payment_sources = sources.sort_by(&:id).map do |source|
|
26
|
+
order.user.wallet.add(source)
|
27
|
+
end
|
28
|
+
|
29
|
+
order.user.wallet.default_wallet_payment_source =
|
30
|
+
wallet_payment_sources.last
|
31
|
+
end
|
23
32
|
end
|
24
33
|
end
|
25
34
|
|
@@ -1,5 +1,6 @@
|
|
1
1
|
# This class is responsible for building a default payment on an order, using a
|
2
|
-
# payment source that is already in the user's "wallet"
|
2
|
+
# payment source that is already in the user's "wallet" and is marked
|
3
|
+
# as being the default payment source.
|
3
4
|
class Spree::Wallet::DefaultPaymentBuilder
|
4
5
|
def initialize(order)
|
5
6
|
@order = order
|
@@ -10,12 +11,11 @@ class Spree::Wallet::DefaultPaymentBuilder
|
|
10
11
|
#
|
11
12
|
# @return [Payment] the unsaved payment to be added, or nil if none.
|
12
13
|
def build
|
13
|
-
|
14
|
-
|
15
|
-
if credit_card.try!(:valid?) && order.payments.from_credit_card.count == 0
|
14
|
+
default = order.user.try!(:wallet).try!(:default_wallet_payment_source)
|
15
|
+
if default && order.payments.where(source_type: default.payment_source_type).none?
|
16
16
|
Spree::Payment.new(
|
17
|
-
|
18
|
-
source:
|
17
|
+
payment_method: default.payment_source.payment_method,
|
18
|
+
source: default.payment_source,
|
19
19
|
)
|
20
20
|
end
|
21
21
|
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
# Interface for accessing and updating a user's active "wallet". A Wallet
|
2
|
+
# is the *active* list of *reusable* payment sources that a user would like to
|
3
|
+
# choose from when placing orders.
|
4
|
+
#
|
5
|
+
# A Wallet is composed of WalletPaymentSources. A WalletPaymentSource is a join table that
|
6
|
+
# links a PaymentSource (e.g. a CreditCard) to a User. One of a user's
|
7
|
+
# WalletPaymentSources may be the 'default' WalletPaymentSource.
|
8
|
+
class Spree::Wallet
|
9
|
+
class Unauthorized < StandardError; end
|
10
|
+
|
11
|
+
attr_reader :user
|
12
|
+
|
13
|
+
def initialize(user)
|
14
|
+
@user = user
|
15
|
+
end
|
16
|
+
|
17
|
+
# Returns an array of the WalletPaymentSources in this wallet.
|
18
|
+
#
|
19
|
+
# @return [Array<WalletPaymentSource>]
|
20
|
+
def wallet_payment_sources
|
21
|
+
user.wallet_payment_sources.to_a
|
22
|
+
end
|
23
|
+
|
24
|
+
# Add a PaymentSource to the wallet.
|
25
|
+
#
|
26
|
+
# @param payment_source [PaymentSource] The payment source to add to the wallet
|
27
|
+
# @return [WalletPaymentSource] the generated WalletPaymentSource
|
28
|
+
def add(payment_source)
|
29
|
+
user.wallet_payment_sources.find_or_create_by!(payment_source: payment_source)
|
30
|
+
end
|
31
|
+
|
32
|
+
# Remove a PaymentSource from the wallet.
|
33
|
+
#
|
34
|
+
# @param payment_source [PaymentSource] The payment source to remove from the wallet
|
35
|
+
# @raise [ActiveRecord::RecordNotFound] if the source is not in the wallet.
|
36
|
+
# @return [WalletPaymentSource] the destroyed WalletPaymentSource
|
37
|
+
def remove(payment_source)
|
38
|
+
user.wallet_payment_sources.find_by!(payment_source: payment_source).destroy!
|
39
|
+
end
|
40
|
+
|
41
|
+
# Find a WalletPaymentSource in the wallet by id.
|
42
|
+
#
|
43
|
+
# @param wallet_payment_source_id [Integer] The id of the WalletPaymentSource.
|
44
|
+
# @return [WalletPaymentSource]
|
45
|
+
def find(wallet_payment_source_id)
|
46
|
+
user.wallet_payment_sources.find_by(id: wallet_payment_source_id)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Find the default WalletPaymentSource for this wallet, if any.
|
50
|
+
# @return [WalletPaymentSource]
|
51
|
+
def default_wallet_payment_source
|
52
|
+
user.wallet_payment_sources.find_by(default: true)
|
53
|
+
end
|
54
|
+
|
55
|
+
# Change the default WalletPaymentSource for this wallet.
|
56
|
+
# @param source [WalletPaymentSource] The payment source to set as the default.
|
57
|
+
# It must be in the wallet already. Pass nil to clear the default.
|
58
|
+
# @return [void]
|
59
|
+
def default_wallet_payment_source=(wallet_payment_source)
|
60
|
+
if wallet_payment_source && !find(wallet_payment_source.id)
|
61
|
+
raise Unauthorized, "wallet_payment_source #{wallet_payment_source.id} does not belong to wallet of user #{user.id}"
|
62
|
+
end
|
63
|
+
|
64
|
+
wallet_payment_source.transaction do
|
65
|
+
# Unset old default
|
66
|
+
default_wallet_payment_source.try!(:update!, default: false)
|
67
|
+
# Set new default
|
68
|
+
wallet_payment_source.try!(:update!, default: true)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class Spree::WalletPaymentSource < ActiveRecord::Base
|
2
|
+
belongs_to :user, class_name: Spree::UserClassHandle.new, foreign_key: 'user_id', inverse_of: :wallet_payment_sources
|
3
|
+
belongs_to :payment_source, polymorphic: true, inverse_of: :wallet_payment_sources
|
4
|
+
|
5
|
+
validates_presence_of :user
|
6
|
+
validates_presence_of :payment_source
|
7
|
+
|
8
|
+
validate :check_for_payment_source_class
|
9
|
+
|
10
|
+
private
|
11
|
+
|
12
|
+
def check_for_payment_source_class
|
13
|
+
if !payment_source.is_a?(Spree::PaymentSource)
|
14
|
+
errors.add(:payment_source, :has_to_be_payment_source_class)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
data/app/models/spree/zone.rb
CHANGED
@@ -185,7 +185,7 @@ module Spree
|
|
185
185
|
def set_zone_members(ids, type)
|
186
186
|
zone_members.destroy_all
|
187
187
|
ids.reject(&:blank?).map do |id|
|
188
|
-
member = ZoneMember.new
|
188
|
+
member = Spree::ZoneMember.new
|
189
189
|
member.zoneable_type = type
|
190
190
|
member.zoneable_id = id
|
191
191
|
members << member
|
@@ -10,7 +10,7 @@
|
|
10
10
|
<% end %>
|
11
11
|
============================================================
|
12
12
|
|
13
|
-
<%= Spree.t('shipment_mailer.shipped_email.track_information', :
|
13
|
+
<%= Spree.t('shipment_mailer.shipped_email.track_information', tracking: @carton.tracking) if @carton.tracking %>
|
14
14
|
<%= Spree.t('shipment_mailer.shipped_email.track_link', :url => @carton.tracking_url) if @carton.tracking_url %>
|
15
15
|
|
16
16
|
<%= Spree.t('shipment_mailer.shipped_email.thanks') %>
|
@@ -31,13 +31,6 @@
|
|
31
31
|
</td>
|
32
32
|
</tr>
|
33
33
|
<% end %>
|
34
|
-
<% if @reimbursement.return_items.awaiting_return.present? && Spree::Config[:expedited_exchanges] %>
|
35
|
-
<tr>
|
36
|
-
<td colspan="3">
|
37
|
-
<%= Spree.t('reimbursement_mailer.reimbursement_email.days_to_send', days: Spree::Config[:expedited_exchanges_days_window]) %>
|
38
|
-
</td>
|
39
|
-
</tr>
|
40
|
-
<% end %>
|
41
34
|
</table>
|
42
35
|
<% end %>
|
43
36
|
</td>
|
@@ -14,9 +14,4 @@
|
|
14
14
|
<% @reimbursement.return_items.exchange_requested.each do |return_item| %>
|
15
15
|
<%= return_item.variant.sku %> <%= raw(return_item.variant.name) %> <%= "(#{raw(return_item.variant.options_text)})" if return_item.variant.options_text.present? %> -> <%= return_item.exchange_variant.sku %> <%= raw(return_item.exchange_variant.name) %> <%= "(#{raw(return_item.exchange_variant.options_text)})" if return_item.exchange_variant.options_text.present? %>
|
16
16
|
<% end %>
|
17
|
-
|
18
|
-
|
19
|
-
<% if @reimbursement.return_items.awaiting_return.present? && Spree::Config[:expedited_exchanges] %>
|
20
|
-
<%= Spree.t('reimbursement_mailer.reimbursement_email.days_to_send', days: Spree::Config[:expedited_exchanges_days_window]) %>
|
21
|
-
<% end %>
|
22
17
|
<% end %>
|
@@ -1,6 +1,6 @@
|
|
1
1
|
<% if target && target.errors.any? %>
|
2
2
|
<div id="errorExplanation" class="errorExplanation" data-hook>
|
3
|
-
<h2><%= Spree.t(:errors_prohibited_this_record_from_being_saved, :
|
3
|
+
<h2><%= Spree.t(:errors_prohibited_this_record_from_being_saved, count: target.errors.count) %>:</h2>
|
4
4
|
<p><%= Spree.t(:there_were_problems_with_the_following_fields) %>:</p>
|
5
5
|
<ul>
|
6
6
|
<% target.errors.full_messages.each do |msg| %>
|
@@ -20,7 +20,7 @@
|
|
20
20
|
<% end %>
|
21
21
|
</table>
|
22
22
|
<p>
|
23
|
-
<%= Spree.t('shipment_mailer.shipped_email.track_information', :
|
23
|
+
<%= Spree.t('shipment_mailer.shipped_email.track_information', tracking: @shipment.tracking) if @shipment.tracking %>
|
24
24
|
</p>
|
25
25
|
<p>
|
26
26
|
<%= Spree.t('shipment_mailer.shipped_email.track_link', :url => @shipment.tracking_url) if @shipment.tracking_url %>
|
@@ -1 +1 @@
|
|
1
|
-
Rails.application.config.assets.precompile
|
1
|
+
Rails.application.config.assets.precompile << 'solidus_core_manifest.js'
|
@@ -82,7 +82,7 @@ FriendlyId.defaults do |config|
|
|
82
82
|
#
|
83
83
|
# config.use Module.new {
|
84
84
|
# def normalize_friendly_id(text)
|
85
|
-
# text.to_slug.normalize! :
|
85
|
+
# text.to_slug.normalize! transliterations: [:russian, :latin]
|
86
86
|
# end
|
87
87
|
# }
|
88
88
|
end
|