spree_core 2.3.13 → 2.4.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/spree.js.coffee.erb +1 -5
- data/app/helpers/spree/base_helper.rb +22 -11
- data/app/helpers/spree/products_helper.rb +8 -7
- data/app/mailers/spree/base_mailer.rb +1 -0
- data/app/mailers/spree/reimbursement_mailer.rb +10 -0
- data/app/mailers/spree/test_mailer.rb +2 -3
- data/app/models/concerns/spree/adjustment_source.rb +24 -0
- data/app/models/concerns/spree/calculated_adjustments.rb +33 -0
- data/app/models/concerns/spree/named_type.rb +12 -0
- data/app/models/concerns/spree/user_address.rb +30 -0
- data/app/models/concerns/spree/user_payment_source.rb +19 -0
- data/app/models/spree/address.rb +13 -6
- data/app/models/spree/adjustment.rb +5 -5
- data/app/models/spree/app_configuration.rb +8 -4
- data/app/models/spree/asset.rb +1 -1
- data/app/models/spree/base.rb +0 -3
- data/app/models/spree/calculator/flat_rate.rb +1 -5
- data/app/models/spree/calculator/returns/default_refund_amount.rb +36 -0
- data/app/models/spree/classification.rb +1 -1
- data/app/models/spree/credit_card.rb +18 -22
- data/app/models/spree/customer_return.rb +70 -0
- data/app/models/spree/exchange.rb +42 -0
- data/app/models/spree/gateway/bogus.rb +3 -3
- data/app/models/spree/image.rb +1 -1
- data/app/models/spree/inventory_unit.rb +32 -8
- data/app/models/spree/item_adjustments.rb +7 -11
- data/app/models/spree/legacy_user.rb +2 -2
- data/app/models/spree/line_item.rb +25 -12
- data/app/models/spree/option_type.rb +1 -1
- data/app/models/spree/option_value.rb +1 -8
- data/app/models/spree/order.rb +163 -145
- data/app/models/spree/order/checkout.rb +35 -23
- data/app/models/spree/order/payments.rb +66 -0
- data/app/models/spree/order_contents.rb +34 -24
- data/app/models/spree/order_populator.rb +6 -4
- data/app/models/spree/order_updater.rb +10 -1
- data/app/models/spree/payment.rb +19 -16
- data/app/models/spree/payment/processing.rb +40 -72
- data/app/models/spree/payment_method.rb +1 -1
- data/app/models/spree/payment_method/check.rb +0 -2
- data/app/models/spree/preference.rb +1 -1
- data/app/models/spree/preferences/preferable.rb +20 -0
- data/app/models/spree/price.rb +13 -3
- data/app/models/spree/product.rb +24 -29
- data/app/models/spree/product_property.rb +0 -2
- data/app/models/spree/promotion.rb +66 -24
- data/app/models/spree/promotion/actions/create_adjustment.rb +2 -2
- data/app/models/spree/promotion/actions/create_item_adjustments.rb +15 -11
- data/app/models/spree/promotion/actions/create_line_items.rb +2 -12
- data/app/models/spree/promotion/rules/first_order.rb +6 -2
- data/app/models/spree/promotion/rules/item_total.rb +42 -4
- data/app/models/spree/promotion/rules/one_use_per_user.rb +24 -0
- data/app/models/spree/promotion/rules/product.rb +13 -11
- data/app/models/spree/promotion/rules/taxon.rb +61 -0
- data/app/models/spree/promotion/rules/user.rb +1 -1
- data/app/models/spree/promotion/rules/user_logged_in.rb +4 -1
- data/app/models/spree/promotion_category.rb +6 -0
- data/app/models/spree/promotion_handler/cart.rb +14 -18
- data/app/models/spree/promotion_handler/coupon.rb +25 -16
- data/app/models/spree/promotion_rule.rb +13 -0
- data/app/models/spree/property.rb +1 -3
- data/app/models/spree/refund.rb +91 -0
- data/app/models/spree/refund_reason.rb +13 -0
- data/app/models/spree/reimbursement.rb +148 -0
- data/app/models/spree/reimbursement/credit.rb +25 -0
- data/app/models/spree/reimbursement/reimbursement_type_engine.rb +56 -0
- data/app/models/spree/reimbursement/reimbursement_type_validator.rb +12 -0
- data/app/models/spree/reimbursement_performer.rb +43 -0
- data/app/models/spree/reimbursement_tax_calculator.rb +38 -0
- data/app/models/spree/reimbursement_type.rb +16 -0
- data/app/models/spree/reimbursement_type/credit.rb +13 -0
- data/app/models/spree/reimbursement_type/exchange.rb +9 -0
- data/app/models/spree/reimbursement_type/original_payment.rb +13 -0
- data/app/models/spree/reimbursement_type/reimbursement_helpers.rb +50 -0
- data/app/models/spree/return_authorization.rb +52 -68
- data/app/models/spree/return_authorization_reason.rb +7 -0
- data/app/models/spree/return_item.rb +230 -0
- data/app/models/spree/return_item/default_eligibility_validator.rb +27 -0
- data/app/models/spree/return_item/eligibility_validator/base_validator.rb +24 -0
- data/app/models/spree/return_item/eligibility_validator/rma_required.rb +17 -0
- data/app/models/spree/return_item/eligibility_validator/time_since_purchase.rb +16 -0
- data/app/models/spree/return_item/exchange_variant_eligibility/same_option_value.rb +34 -0
- data/app/models/spree/return_item/exchange_variant_eligibility/same_product.rb +10 -0
- data/app/models/spree/returns_calculator.rb +8 -0
- data/app/models/spree/shipment.rb +209 -154
- data/app/models/spree/shipment_handler.rb +43 -0
- data/app/models/spree/shipping_calculator.rb +1 -1
- data/app/models/spree/shipping_category.rb +2 -2
- data/app/models/spree/shipping_method.rb +1 -1
- data/app/models/spree/shipping_method_category.rb +1 -1
- data/app/models/spree/shipping_rate.rb +4 -0
- data/app/models/spree/stock/adjuster.rb +10 -11
- data/app/models/spree/stock/availability_validator.rb +6 -10
- data/app/models/spree/stock/content_item.rb +48 -0
- data/app/models/spree/stock/coordinator.rb +14 -7
- data/app/models/spree/stock/estimator.rb +1 -1
- data/app/models/spree/stock/inventory_unit_builder.rb +21 -0
- data/app/models/spree/stock/package.rb +38 -51
- data/app/models/spree/stock/packer.rb +13 -11
- data/app/models/spree/stock/prioritizer.rb +7 -7
- data/app/models/spree/stock/splitter/base.rb +2 -2
- data/app/models/spree/stock_item.rb +6 -9
- data/app/models/spree/stock_location.rb +17 -25
- data/app/models/spree/stock_movement.rb +1 -8
- data/app/models/spree/stock_transfer.rb +0 -2
- data/app/models/spree/store.rb +1 -1
- data/app/models/spree/tax_category.rb +2 -2
- data/app/models/spree/tax_rate.rb +16 -22
- data/app/models/spree/taxon.rb +1 -1
- data/app/models/spree/variant.rb +45 -23
- data/app/models/spree/zone.rb +17 -17
- data/app/models/spree/zone_member.rb +1 -1
- data/app/views/layouts/spree/base_mailer.html.erb +784 -0
- data/app/views/spree/order_mailer/cancel_email.html.erb +45 -0
- data/app/views/spree/order_mailer/cancel_email.text.erb +2 -2
- data/app/views/spree/order_mailer/confirm_email.html.erb +84 -0
- data/app/views/spree/order_mailer/confirm_email.text.erb +2 -2
- data/app/views/spree/reimbursement_mailer/reimbursement_email.text.erb +22 -0
- data/app/views/spree/shared/_base_mailer_footer.html.erb +20 -0
- data/app/views/spree/shared/_base_mailer_header.html.erb +31 -0
- data/app/views/spree/shipment_mailer/shipped_email.html.erb +34 -0
- data/app/views/spree/test_mailer/test_email.html.erb +40 -0
- data/app/views/spree/test_mailer/test_email.text.erb +2 -2
- data/config/initializers/friendly_id.rb +88 -0
- data/config/initializers/premailer_assets.rb +1 -0
- data/config/initializers/user_class_extensions.rb +9 -22
- data/config/locales/en.yml +180 -12
- data/db/default/spree/states.rb +73 -55
- data/db/migrate/20130213191427_create_default_stock.rb +1 -0
- data/db/migrate/20130807024301_upgrade_adjustments.rb +4 -5
- data/db/migrate/20140309033438_create_store_from_preferences.rb +0 -7
- data/db/migrate/20140318191500_create_spree_taxons_promotion_rules.rb +8 -0
- data/db/migrate/20140530024945_move_order_token_from_tokenized_permission.rb +1 -1
- data/db/migrate/20140601011216_set_shipment_total_for_users_upgrading.rb +5 -3
- data/db/migrate/20140625214618_create_spree_refunds.rb +12 -0
- data/db/migrate/20140702140656_create_spree_return_authorization_inventory_unit.rb +12 -0
- data/db/migrate/20140707125621_rename_return_authorization_inventory_unit_to_return_items.rb +5 -0
- data/db/migrate/20140709160534_backfill_line_item_pre_tax_amount.rb +10 -0
- data/db/migrate/20140710041921_recreate_spree_return_authorizations.rb +55 -0
- data/db/migrate/20140710181204_add_amount_fields_to_return_items.rb +7 -0
- data/db/migrate/20140710190048_drop_return_authorization_amount.rb +5 -0
- data/db/migrate/20140713140455_create_spree_return_authorization_reasons.rb +28 -0
- data/db/migrate/20140713140527_create_spree_refund_reasons.rb +14 -0
- data/db/migrate/20140713142214_rename_return_authorization_reason.rb +5 -0
- data/db/migrate/20140715182625_create_spree_promotion_categories.rb +11 -0
- data/db/migrate/20140716204111_drop_received_at_on_return_items.rb +9 -0
- data/db/migrate/20140716212330_add_reception_and_acceptance_status_to_return_items.rb +6 -0
- data/db/migrate/20140717155155_create_default_refund_reason.rb +9 -0
- data/db/migrate/20140717185932_add_default_to_spree_stock_locations.rb +5 -0
- data/db/migrate/20140718133010_create_spree_customer_returns.rb +9 -0
- data/db/migrate/20140718133349_add_customer_return_id_to_return_item.rb +6 -0
- data/db/migrate/20140718195325_create_friendly_id_slugs.rb +15 -0
- data/db/migrate/20140723004419_rename_spree_refund_return_authorization_id.rb +5 -0
- data/db/migrate/20140723152808_increase_return_item_pre_tax_amount_precision.rb +13 -0
- data/db/migrate/20140723214541_copy_product_slugs_to_slug_history.rb +15 -0
- data/db/migrate/20140725131539_create_spree_reimbursements.rb +21 -0
- data/db/migrate/20140728225422_add_promotionable_to_spree_products.rb +5 -0
- data/db/migrate/20140729133613_add_exchange_inventory_unit_foreign_keys.rb +7 -0
- data/db/migrate/20140730155938_add_acceptance_status_errors_to_return_item.rb +5 -0
- data/db/migrate/20140731150017_create_spree_reimbursement_types.rb +20 -0
- data/db/migrate/20140805171035_add_default_to_spree_credit_cards.rb +5 -0
- data/db/migrate/20140805171219_make_existing_credit_cards_default.rb +10 -0
- data/db/migrate/20140806144901_add_type_to_reimbursement_type.rb +9 -0
- data/db/migrate/20140808184039_create_spree_reimbursement_credits.rb +10 -0
- data/db/migrate/20140827170513_add_meta_title_to_spree_products.rb +7 -0
- data/db/migrate/20140924164824_add_code_to_spree_tax_categories.rb +5 -0
- data/db/migrate/20141002191113_add_code_to_spree_shipping_methods.rb +5 -0
- data/db/migrate/20141007230328_add_cancel_audit_fields_to_spree_orders.rb +6 -0
- data/db/migrate/20141009204607_add_store_id_to_orders.rb +8 -0
- data/lib/generators/spree/install/install_generator.rb +7 -3
- data/lib/spree/core.rb +11 -10
- data/lib/spree/core/controller_helpers/common.rb +3 -10
- data/lib/spree/core/controller_helpers/order.rb +15 -12
- data/lib/spree/core/controller_helpers/strong_parameters.rb +9 -9
- data/lib/spree/core/engine.rb +8 -1
- data/lib/spree/core/importer/order.rb +5 -17
- data/lib/spree/core/search/base.rb +1 -1
- data/lib/spree/core/validators/email.rb +1 -1
- data/lib/spree/core/version.rb +1 -1
- data/lib/spree/instrumentation.rb +41 -0
- data/lib/spree/migrations.rb +3 -7
- data/lib/spree/money.rb +2 -2
- data/lib/spree/permitted_attributes.rb +10 -9
- data/lib/spree/testing_support/ability_helpers.rb +25 -25
- data/lib/spree/testing_support/authorization_helpers.rb +3 -5
- data/lib/spree/testing_support/capybara_ext.rb +2 -2
- data/lib/spree/testing_support/factories/calculator_factory.rb +0 -8
- data/lib/spree/testing_support/factories/credit_card_factory.rb +1 -1
- data/lib/spree/testing_support/factories/customer_return_factory.rb +31 -0
- data/lib/spree/testing_support/factories/inventory_unit_factory.rb +1 -0
- data/lib/spree/testing_support/factories/line_item_factory.rb +2 -1
- data/lib/spree/testing_support/factories/order_factory.rb +11 -6
- data/lib/spree/testing_support/factories/promotion_category_factory.rb +6 -0
- data/lib/spree/testing_support/factories/promotion_factory.rb +9 -7
- data/lib/spree/testing_support/factories/refund_factory.rb +14 -0
- data/lib/spree/testing_support/factories/reimbursement_factory.rb +16 -0
- data/lib/spree/testing_support/factories/reimbursement_type_factory.rb +7 -0
- data/lib/spree/testing_support/factories/return_authorization_factory.rb +9 -3
- data/lib/spree/testing_support/factories/return_item_factory.rb +10 -0
- data/lib/spree/testing_support/factories/shipment_factory.rb +1 -0
- data/lib/spree/testing_support/factories/shipping_method_factory.rb +3 -2
- data/lib/spree/testing_support/factories/stock_factory.rb +12 -11
- data/lib/spree/testing_support/flash.rb +2 -2
- data/lib/tasks/email.rake +7 -0
- data/lib/tasks/exchanges.rake +70 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_et.js +23 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_eu.js +25 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_hr.js +25 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_ka.js +25 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_ko.js +25 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_my.js +25 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_pt_BR.js +26 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_pt_PT.js +26 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_sl.js +25 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_sv.js +23 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_uk.js +25 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_zh.js +25 -0
- data/vendor/assets/javascripts/jquery.validate/localization/messages_zh_TW.js +26 -0
- metadata +163 -47
- data/app/models/concerns/spree/ransackable_attributes.rb +0 -19
- data/db/migrate/20141021194502_add_state_lock_version_to_order.rb +0 -5
- data/db/migrate/20141101231208_fix_adjustment_order_presence.rb +0 -13
- data/db/migrate/20141105213646_update_classifications_positions.rb +0 -9
- data/db/migrate/20141120135441_add_guest_token_index_to_spree_orders.rb +0 -5
- data/db/migrate/20150515211137_fix_adjustment_order_id.rb +0 -70
- data/lib/spree/core/adjustment_source.rb +0 -26
- data/lib/spree/core/calculated_adjustments.rb +0 -35
- data/lib/spree/core/controller_helpers.rb +0 -20
- data/lib/spree/core/user_address.rb +0 -32
- data/lib/spree/core/user_payment_source.rb +0 -20
- data/lib/spree/localized_number.rb +0 -20
@@ -0,0 +1,36 @@
|
|
1
|
+
require_dependency 'spree/returns_calculator'
|
2
|
+
|
3
|
+
module Spree
|
4
|
+
module Calculator::Returns
|
5
|
+
class DefaultRefundAmount < ReturnsCalculator
|
6
|
+
|
7
|
+
def self.description
|
8
|
+
Spree.t(:default_refund_amount)
|
9
|
+
end
|
10
|
+
|
11
|
+
def compute(return_item)
|
12
|
+
return 0.0.to_d if return_item.exchange_requested?
|
13
|
+
weighted_order_adjustment_amount(return_item.inventory_unit) + weighted_line_item_pre_tax_amount(return_item.inventory_unit)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def weighted_order_adjustment_amount(inventory_unit)
|
19
|
+
inventory_unit.order.adjustments.eligible.non_tax.sum(:amount) * percentage_of_order_total(inventory_unit)
|
20
|
+
end
|
21
|
+
|
22
|
+
def weighted_line_item_pre_tax_amount(inventory_unit)
|
23
|
+
inventory_unit.line_item.pre_tax_amount * percentage_of_line_item(inventory_unit)
|
24
|
+
end
|
25
|
+
|
26
|
+
def percentage_of_order_total(inventory_unit)
|
27
|
+
return 0.0 if inventory_unit.order.pre_tax_item_amount.zero?
|
28
|
+
weighted_line_item_pre_tax_amount(inventory_unit) / inventory_unit.order.pre_tax_item_amount
|
29
|
+
end
|
30
|
+
|
31
|
+
def percentage_of_line_item(inventory_unit)
|
32
|
+
1 / BigDecimal.new(inventory_unit.line_item.quantity)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
module Spree
|
2
2
|
class Classification < Spree::Base
|
3
3
|
self.table_name = 'spree_products_taxons'
|
4
|
-
acts_as_list
|
4
|
+
acts_as_list
|
5
5
|
belongs_to :product, class_name: "Spree::Product", inverse_of: :classifications
|
6
6
|
belongs_to :taxon, class_name: "Spree::Taxon", inverse_of: :classifications
|
7
7
|
|
@@ -1,9 +1,12 @@
|
|
1
1
|
module Spree
|
2
2
|
class CreditCard < Spree::Base
|
3
3
|
belongs_to :payment_method
|
4
|
+
belongs_to :user, class_name: Spree.user_class, foreign_key: 'user_id'
|
4
5
|
has_many :payments, as: :source
|
5
6
|
|
6
|
-
|
7
|
+
before_save :set_last_digits
|
8
|
+
|
9
|
+
after_save :ensure_one_default
|
7
10
|
|
8
11
|
attr_accessor :encrypted_data,
|
9
12
|
:number,
|
@@ -18,6 +21,7 @@ module Spree
|
|
18
21
|
validate :expiry_not_in_the_past
|
19
22
|
|
20
23
|
scope :with_payment_profile, -> { where('gateway_customer_profile_id IS NOT NULL') }
|
24
|
+
scope :default, -> { where(default: true) }
|
21
25
|
|
22
26
|
# needed for some of the ActiveMerchant gateways (eg. SagePay)
|
23
27
|
alias_attribute :brand, :cc_type
|
@@ -35,7 +39,7 @@ module Spree
|
|
35
39
|
return unless expiry.present?
|
36
40
|
|
37
41
|
self[:month], self[:year] =
|
38
|
-
if expiry.match(/\d\s?\/\s?\d/) # will match mm/yy and mm / yyyy
|
42
|
+
if expiry.match(/\d{2}\s?\/\s?\d{2,4}/) # will match mm/yy and mm / yyyy
|
39
43
|
expiry.delete(' ').split('/')
|
40
44
|
elsif match = expiry.match(/(\d{2})(\d{2,4})/) # will match mmyy and mmyyyy
|
41
45
|
[match[1], match[2]]
|
@@ -44,7 +48,7 @@ module Spree
|
|
44
48
|
self[:year] = "20" + self[:year] if self[:year].length == 2
|
45
49
|
self[:year] = self[:year].to_i
|
46
50
|
end
|
47
|
-
self[:month] = self[:month].to_i
|
51
|
+
self[:month] = self[:month].to_i if self[:month]
|
48
52
|
end
|
49
53
|
|
50
54
|
def number=(num)
|
@@ -63,6 +67,12 @@ module Spree
|
|
63
67
|
end
|
64
68
|
end
|
65
69
|
|
70
|
+
def set_last_digits
|
71
|
+
number.to_s.gsub!(/\s/,'')
|
72
|
+
verification_value.to_s.gsub!(/\s/,'')
|
73
|
+
self.last_digits ||= number.to_s.length <= 4 ? number : number.to_s.slice(-4..-1)
|
74
|
+
end
|
75
|
+
|
66
76
|
def try_type_from_number
|
67
77
|
numbers = number.delete(' ') if number
|
68
78
|
CARD_TYPES.find{|type, pattern| return type.to_s if numbers =~ pattern}.to_s
|
@@ -94,9 +104,7 @@ module Spree
|
|
94
104
|
# Indicates whether its possible to credit the payment. Note that most gateways require that the
|
95
105
|
# payment be settled first which generally happens within 12-24 hours of the transaction.
|
96
106
|
def can_credit?(payment)
|
97
|
-
|
98
|
-
return false unless payment.order.payment_state == 'credit_owed'
|
99
|
-
payment.credit_allowed > 0
|
107
|
+
payment.completed? && payment.credit_allowed > 0
|
100
108
|
end
|
101
109
|
|
102
110
|
def has_payment_profile?
|
@@ -144,24 +152,12 @@ module Spree
|
|
144
152
|
!self.encrypted_data.present? && !self.has_payment_profile?
|
145
153
|
end
|
146
154
|
|
147
|
-
def
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
end
|
152
|
-
|
153
|
-
def set_missing_info
|
154
|
-
set_last_digits
|
155
|
-
if has_payment_profile?
|
156
|
-
if matching_card = self.class.where(gateway_customer_profile_id: self.gateway_customer_profile_id, gateway_payment_profile_id: self.gateway_payment_profile_id).first
|
157
|
-
self.cc_type = matching_card.cc_type
|
158
|
-
self.last_digits = matching_card.last_digits
|
159
|
-
self.month = matching_card.month
|
160
|
-
self.name = matching_card.name
|
161
|
-
self.year = matching_card.year
|
155
|
+
def ensure_one_default
|
156
|
+
if self.user_id && self.default
|
157
|
+
CreditCard.where(default: true).where.not(id: self.id).where(user_id: self.user_id).each do |ucc|
|
158
|
+
ucc.update_columns(default: false)
|
162
159
|
end
|
163
160
|
end
|
164
161
|
end
|
165
|
-
|
166
162
|
end
|
167
163
|
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module Spree
|
2
|
+
class CustomerReturn < Spree::Base
|
3
|
+
belongs_to :stock_location
|
4
|
+
|
5
|
+
has_many :return_items, inverse_of: :customer_return
|
6
|
+
has_many :return_authorizations, through: :return_items
|
7
|
+
has_many :reimbursements, inverse_of: :customer_return
|
8
|
+
|
9
|
+
after_create :process_return!
|
10
|
+
before_create :generate_number
|
11
|
+
|
12
|
+
validates :return_items, presence: true
|
13
|
+
validates :stock_location, presence: true
|
14
|
+
validate :return_items_belong_to_same_order
|
15
|
+
|
16
|
+
accepts_nested_attributes_for :return_items
|
17
|
+
|
18
|
+
def pre_tax_total
|
19
|
+
return_items.sum(:pre_tax_amount)
|
20
|
+
end
|
21
|
+
|
22
|
+
def display_pre_tax_total
|
23
|
+
Spree::Money.new(pre_tax_total, { currency: Spree::Config[:currency] })
|
24
|
+
end
|
25
|
+
|
26
|
+
# Temporarily tie a customer_return to one order
|
27
|
+
def order
|
28
|
+
return nil if return_items.blank?
|
29
|
+
return_items.first.inventory_unit.order
|
30
|
+
end
|
31
|
+
|
32
|
+
def order_id
|
33
|
+
order.try(:id)
|
34
|
+
end
|
35
|
+
|
36
|
+
def fully_reimbursed?
|
37
|
+
completely_decided? && return_items.accepted.includes(:reimbursement).all? { |return_item| return_item.reimbursement.try(:reimbursed?) }
|
38
|
+
end
|
39
|
+
|
40
|
+
def completely_decided?
|
41
|
+
!return_items.undecided.exists?
|
42
|
+
end
|
43
|
+
|
44
|
+
private
|
45
|
+
|
46
|
+
def generate_number
|
47
|
+
self.number ||= loop do
|
48
|
+
random = "CR#{Array.new(9){rand(9)}.join}"
|
49
|
+
break random unless self.class.exists?(number: random)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def process_return!
|
54
|
+
return_items.each(&:receive!)
|
55
|
+
order.return! if order.all_inventory_units_returned?
|
56
|
+
end
|
57
|
+
|
58
|
+
def return_items_belong_to_same_order
|
59
|
+
if return_items.select{ |return_item| return_item.inventory_unit.order_id != order_id }.any?
|
60
|
+
errors.add(:base, Spree.t(:return_items_cannot_be_associated_with_multiple_orders))
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def inventory_units
|
65
|
+
return_items.flat_map(&:inventory_unit)
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module Spree
|
2
|
+
class Exchange
|
3
|
+
|
4
|
+
def initialize(order, reimbursement_objects)
|
5
|
+
@order = order
|
6
|
+
@reimbursement_objects = reimbursement_objects
|
7
|
+
end
|
8
|
+
|
9
|
+
def description
|
10
|
+
@reimbursement_objects.map do |reimbursement_object|
|
11
|
+
"#{reimbursement_object.variant.options_text} => #{reimbursement_object.exchange_variant.options_text}"
|
12
|
+
end.join(" | ")
|
13
|
+
end
|
14
|
+
|
15
|
+
def display_amount
|
16
|
+
Spree::Money.new @reimbursement_objects.map(&:total).sum
|
17
|
+
end
|
18
|
+
|
19
|
+
def perform!
|
20
|
+
shipments = Spree::Stock::Coordinator.new(@order, @reimbursement_objects.map(&:build_exchange_inventory_unit)).shipments
|
21
|
+
@order.shipments += shipments
|
22
|
+
@order.save!
|
23
|
+
shipments.each do |shipment|
|
24
|
+
shipment.update!(@order)
|
25
|
+
shipment.finalize!
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_key
|
30
|
+
nil
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.param_key
|
34
|
+
"spree_exchange"
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.model_name
|
38
|
+
Spree::Exchange
|
39
|
+
end
|
40
|
+
|
41
|
+
end
|
42
|
+
end
|
@@ -18,10 +18,10 @@ module Spree
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def create_profile(payment)
|
21
|
+
return if payment.source.has_payment_profile?
|
21
22
|
# simulate the storage of credit card profile using remote service
|
22
|
-
|
23
|
-
|
24
|
-
end
|
23
|
+
success = VALID_CCS.include? payment.source.number
|
24
|
+
payment.source.update_attributes(:gateway_customer_profile_id => generate_profile_id(success))
|
25
25
|
end
|
26
26
|
|
27
27
|
def authorize(money, credit_card, options = {})
|
data/app/models/spree/image.rb
CHANGED
@@ -33,7 +33,7 @@ module Spree
|
|
33
33
|
# if there are errors from the plugin, then add a more meaningful message
|
34
34
|
def no_attachment_errors
|
35
35
|
unless attachment.errors.empty?
|
36
|
-
# uncomment this to get rid of the less-than-useful
|
36
|
+
# uncomment this to get rid of the less-than-useful interim messages
|
37
37
|
# errors.clear
|
38
38
|
errors.add :attachment, "Paperclip returned errors for file '#{attachment_file_name}' - check ImageMagick installation or image source file."
|
39
39
|
false
|
@@ -3,11 +3,16 @@ module Spree
|
|
3
3
|
belongs_to :variant, class_name: "Spree::Variant", inverse_of: :inventory_units
|
4
4
|
belongs_to :order, class_name: "Spree::Order", inverse_of: :inventory_units
|
5
5
|
belongs_to :shipment, class_name: "Spree::Shipment", touch: true, inverse_of: :inventory_units
|
6
|
-
belongs_to :return_authorization, class_name: "Spree::ReturnAuthorization"
|
6
|
+
belongs_to :return_authorization, class_name: "Spree::ReturnAuthorization"
|
7
7
|
belongs_to :line_item, class_name: "Spree::LineItem", inverse_of: :inventory_units
|
8
8
|
|
9
|
+
has_many :return_items, inverse_of: :inventory_unit
|
10
|
+
has_one :original_return_item, class_name: "Spree::ReturnItem", foreign_key: :exchange_inventory_unit_id
|
11
|
+
|
9
12
|
scope :backordered, -> { where state: 'backordered' }
|
13
|
+
scope :on_hand, -> { where state: 'on_hand' }
|
10
14
|
scope :shipped, -> { where state: 'shipped' }
|
15
|
+
scope :returned, -> { where state: 'returned' }
|
11
16
|
scope :backordered_per_variant, ->(stock_item) do
|
12
17
|
includes(:shipment, :order)
|
13
18
|
.where("spree_shipments.state != 'canceled'").references(:shipment)
|
@@ -21,7 +26,7 @@ module Spree
|
|
21
26
|
event :fill_backorder do
|
22
27
|
transition to: :on_hand, from: :backordered
|
23
28
|
end
|
24
|
-
after_transition on: :fill_backorder, do: :
|
29
|
+
after_transition on: :fill_backorder, do: :update_order
|
25
30
|
|
26
31
|
event :ship do
|
27
32
|
transition to: :shipped, if: :allow_ship?
|
@@ -33,8 +38,8 @@ module Spree
|
|
33
38
|
end
|
34
39
|
|
35
40
|
# This was refactored from a simpler query because the previous implementation
|
36
|
-
#
|
37
|
-
# to ActiveRecord `joins(shipment: :stock_location)` only
|
41
|
+
# led to issues once users tried to modify the objects returned. That's due
|
42
|
+
# to ActiveRecord `joins(shipment: :stock_location)` only returning readonly
|
38
43
|
# objects
|
39
44
|
#
|
40
45
|
# Returns an array of backordered inventory units as per a given stock item
|
@@ -63,16 +68,35 @@ module Spree
|
|
63
68
|
Spree::Variant.unscoped { super }
|
64
69
|
end
|
65
70
|
|
71
|
+
def current_or_new_return_item
|
72
|
+
Spree::ReturnItem.from_inventory_unit(self)
|
73
|
+
end
|
74
|
+
|
75
|
+
def additional_tax_total
|
76
|
+
line_item.additional_tax_total * percentage_of_line_item
|
77
|
+
end
|
78
|
+
|
79
|
+
def included_tax_total
|
80
|
+
line_item.included_tax_total * percentage_of_line_item
|
81
|
+
end
|
82
|
+
|
66
83
|
private
|
67
84
|
|
68
85
|
def allow_ship?
|
69
|
-
|
86
|
+
self.on_hand?
|
70
87
|
end
|
71
88
|
|
72
|
-
def
|
89
|
+
def update_order
|
73
90
|
self.reload
|
74
|
-
order.
|
91
|
+
order.update!
|
92
|
+
end
|
93
|
+
|
94
|
+
def percentage_of_line_item
|
95
|
+
1 / BigDecimal.new(line_item.quantity)
|
96
|
+
end
|
97
|
+
|
98
|
+
def current_return_item
|
99
|
+
return_items.not_cancelled.first
|
75
100
|
end
|
76
101
|
end
|
77
102
|
end
|
78
|
-
|
@@ -9,9 +9,8 @@ module Spree
|
|
9
9
|
|
10
10
|
def initialize(item)
|
11
11
|
@item = item
|
12
|
-
|
13
12
|
# Don't attempt to reload the item from the DB if it's not there
|
14
|
-
@item.reload if @item.
|
13
|
+
@item.reload if @item.persisted?
|
15
14
|
end
|
16
15
|
|
17
16
|
def update
|
@@ -28,20 +27,17 @@ module Spree
|
|
28
27
|
#
|
29
28
|
# It also fits the criteria for sales tax as outlined here:
|
30
29
|
# http://www.boe.ca.gov/formspubs/pub113/
|
31
|
-
#
|
30
|
+
#
|
32
31
|
# Tax adjustments come in not one but *two* exciting flavours:
|
33
32
|
# Included & additional
|
34
33
|
|
35
34
|
# Included tax adjustments are those which are included in the price.
|
36
|
-
# These ones should not
|
35
|
+
# These ones should not affect the eventual total price.
|
37
36
|
#
|
38
|
-
# Additional tax adjustments are the opposite
|
37
|
+
# Additional tax adjustments are the opposite, affecting the final total.
|
39
38
|
promo_total = 0
|
40
39
|
run_callbacks :promo_adjustments do
|
41
|
-
promotion_total = adjustments.promotion.reload.map
|
42
|
-
adjustment.update!(@item)
|
43
|
-
end.compact.sum
|
44
|
-
|
40
|
+
promotion_total = adjustments.promotion.reload.map(&:update!).compact.sum
|
45
41
|
unless promotion_total == 0
|
46
42
|
choose_best_promotion_adjustment
|
47
43
|
end
|
@@ -52,7 +48,7 @@ module Spree
|
|
52
48
|
additional_tax_total = 0
|
53
49
|
run_callbacks :tax_adjustments do
|
54
50
|
tax = (item.respond_to?(:all_adjustments) ? item.all_adjustments : item.adjustments).tax
|
55
|
-
included_tax_total = tax.
|
51
|
+
included_tax_total = tax.included.reload.map(&:update!).compact.sum
|
56
52
|
additional_tax_total = tax.additional.reload.map(&:update!).compact.sum
|
57
53
|
end
|
58
54
|
|
@@ -70,7 +66,7 @@ module Spree
|
|
70
66
|
# have the same amount, then it will pick the latest one.
|
71
67
|
def choose_best_promotion_adjustment
|
72
68
|
if best_promotion_adjustment
|
73
|
-
other_promotions = self.adjustments.promotion.where(
|
69
|
+
other_promotions = self.adjustments.promotion.where.not(id: best_promotion_adjustment.id)
|
74
70
|
other_promotions.update_all(:eligible => false)
|
75
71
|
end
|
76
72
|
end
|
@@ -1,8 +1,8 @@
|
|
1
1
|
# Default implementation of User. This class is intended to be modified by extensions (ex. spree_auth_devise)
|
2
2
|
module Spree
|
3
3
|
class LegacyUser < Spree::Base
|
4
|
-
include
|
5
|
-
include
|
4
|
+
include UserAddress
|
5
|
+
include UserPaymentSource
|
6
6
|
|
7
7
|
self.table_name = 'spree_users'
|
8
8
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Spree
|
2
2
|
class LineItem < Spree::Base
|
3
|
-
before_validation :
|
3
|
+
before_validation :invalid_quantity_check
|
4
4
|
belongs_to :order, class_name: "Spree::Order", inverse_of: :line_items, touch: true
|
5
5
|
belongs_to :variant, class_name: "Spree::Variant", inverse_of: :line_items
|
6
6
|
belongs_to :tax_category, class_name: "Spree::TaxCategory"
|
@@ -24,7 +24,6 @@ module Spree
|
|
24
24
|
|
25
25
|
validate :ensure_proper_currency
|
26
26
|
before_destroy :update_inventory
|
27
|
-
before_destroy :destroy_inventory_units
|
28
27
|
|
29
28
|
after_save :update_inventory
|
30
29
|
after_save :update_adjustments
|
@@ -35,9 +34,6 @@ module Spree
|
|
35
34
|
|
36
35
|
attr_accessor :target_shipment
|
37
36
|
|
38
|
-
self.whitelisted_ransackable_associations = ['variant']
|
39
|
-
self.whitelisted_ransackable_attributes = ['variant_id']
|
40
|
-
|
41
37
|
def copy_price
|
42
38
|
if variant
|
43
39
|
self.price = variant.price if price.nil?
|
@@ -61,8 +57,12 @@ module Spree
|
|
61
57
|
amount + promo_total
|
62
58
|
end
|
63
59
|
|
60
|
+
def discounted_money
|
61
|
+
Spree::Money.new(discounted_amount, { currency: currency })
|
62
|
+
end
|
63
|
+
|
64
64
|
def final_amount
|
65
|
-
amount + adjustment_total
|
65
|
+
amount + adjustment_total
|
66
66
|
end
|
67
67
|
alias total final_amount
|
68
68
|
|
@@ -77,7 +77,7 @@ module Spree
|
|
77
77
|
alias display_total money
|
78
78
|
alias display_amount money
|
79
79
|
|
80
|
-
def
|
80
|
+
def invalid_quantity_check
|
81
81
|
self.quantity = 0 if quantity.nil? || quantity < 0
|
82
82
|
end
|
83
83
|
|
@@ -99,6 +99,23 @@ module Spree
|
|
99
99
|
Spree::Variant.unscoped { super }
|
100
100
|
end
|
101
101
|
|
102
|
+
def options=(options={})
|
103
|
+
opts = options.dup # we will be deleting from the hash, so leave the caller's copy intact
|
104
|
+
|
105
|
+
currency = opts.delete(:currency) || order.try(:currency)
|
106
|
+
|
107
|
+
if currency
|
108
|
+
self.currency = currency
|
109
|
+
self.price = variant.price_in(currency).amount +
|
110
|
+
variant.price_modifier_amount_in(currency, opts)
|
111
|
+
else
|
112
|
+
self.price = variant.price +
|
113
|
+
variant.price_modifier_amount(opts)
|
114
|
+
end
|
115
|
+
|
116
|
+
self.assign_attributes opts
|
117
|
+
end
|
118
|
+
|
102
119
|
private
|
103
120
|
def update_inventory
|
104
121
|
if (changed? || target_shipment.present?) && self.order.has_checkout_step?("delivery")
|
@@ -106,13 +123,9 @@ module Spree
|
|
106
123
|
end
|
107
124
|
end
|
108
125
|
|
109
|
-
def destroy_inventory_units
|
110
|
-
inventory_units.destroy_all
|
111
|
-
end
|
112
|
-
|
113
126
|
def update_adjustments
|
114
127
|
if quantity_changed?
|
115
|
-
update_tax_charge # Called to ensure pre_tax_amount is updated.
|
128
|
+
update_tax_charge # Called to ensure pre_tax_amount is updated.
|
116
129
|
recalculate_adjustments
|
117
130
|
end
|
118
131
|
end
|