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,43 @@
|
|
1
|
+
module Spree
|
2
|
+
class ShipmentHandler
|
3
|
+
class << self
|
4
|
+
def factory(shipment)
|
5
|
+
# Do we have a specialized shipping-method-specific handler? e.g:
|
6
|
+
# Given shipment.shipping_method = Spree::ShippingMethod::DigitalDownload
|
7
|
+
# do we have Spree::ShipmentHandler::DigitalDownload?
|
8
|
+
if sm_handler = "Spree::ShipmentHandler::#{shipment.shipping_method.name.split('::').last}".constantize rescue false
|
9
|
+
sm_handler.new(shipment)
|
10
|
+
else
|
11
|
+
new(shipment)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def initialize(shipment)
|
17
|
+
@shipment = shipment
|
18
|
+
end
|
19
|
+
|
20
|
+
def perform
|
21
|
+
@shipment.inventory_units.each &:ship!
|
22
|
+
@shipment.process_order_payments if Spree::Config[:auto_capture_on_dispatch]
|
23
|
+
send_shipped_email
|
24
|
+
@shipment.touch :shipped_at
|
25
|
+
update_order_shipment_state
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
def send_shipped_email
|
30
|
+
ShipmentMailer.shipped_email(@shipment.id).deliver
|
31
|
+
end
|
32
|
+
|
33
|
+
def update_order_shipment_state
|
34
|
+
order = @shipment.order
|
35
|
+
|
36
|
+
new_state = OrderUpdater.new(order).update_shipment_state
|
37
|
+
order.update_columns(
|
38
|
+
shipment_state: new_state,
|
39
|
+
updated_at: Time.now,
|
40
|
+
)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -2,7 +2,7 @@ module Spree
|
|
2
2
|
class ShippingCategory < Spree::Base
|
3
3
|
validates :name, presence: true
|
4
4
|
has_many :products, inverse_of: :shipping_category
|
5
|
-
has_many :shipping_method_categories
|
5
|
+
has_many :shipping_method_categories
|
6
6
|
has_many :shipping_methods, through: :shipping_method_categories
|
7
7
|
end
|
8
|
-
end
|
8
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
module Spree
|
2
2
|
class ShippingMethodCategory < Spree::Base
|
3
3
|
belongs_to :shipping_method, class_name: 'Spree::ShippingMethod'
|
4
|
-
belongs_to :shipping_category, class_name: 'Spree::ShippingCategory'
|
4
|
+
belongs_to :shipping_category, class_name: 'Spree::ShippingCategory'
|
5
5
|
end
|
6
6
|
end
|
@@ -3,25 +3,24 @@
|
|
3
3
|
module Spree
|
4
4
|
module Stock
|
5
5
|
class Adjuster
|
6
|
-
attr_accessor :
|
6
|
+
attr_accessor :inventory_unit, :status, :fulfilled
|
7
7
|
|
8
|
-
def initialize(
|
9
|
-
@
|
10
|
-
@need = quantity
|
8
|
+
def initialize(inventory_unit, status)
|
9
|
+
@inventory_unit = inventory_unit
|
11
10
|
@status = status
|
11
|
+
@fulfilled = false
|
12
12
|
end
|
13
13
|
|
14
|
-
def adjust(
|
15
|
-
if
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
@need -= item.quantity
|
14
|
+
def adjust(package)
|
15
|
+
if fulfilled?
|
16
|
+
package.remove(inventory_unit)
|
17
|
+
else
|
18
|
+
self.fulfilled = true
|
20
19
|
end
|
21
20
|
end
|
22
21
|
|
23
22
|
def fulfilled?
|
24
|
-
|
23
|
+
fulfilled
|
25
24
|
end
|
26
25
|
end
|
27
26
|
end
|
@@ -5,20 +5,16 @@ module Spree
|
|
5
5
|
unit_count = line_item.inventory_units.size
|
6
6
|
return if unit_count >= line_item.quantity
|
7
7
|
quantity = line_item.quantity - unit_count
|
8
|
-
return if quantity.zero?
|
9
8
|
|
10
9
|
quantifier = Stock::Quantifier.new(line_item.variant)
|
11
10
|
|
12
|
-
|
11
|
+
unless quantifier.can_supply? quantity
|
12
|
+
variant = line_item.variant
|
13
|
+
display_name = %Q{#{variant.name}}
|
14
|
+
display_name += %Q{ (#{variant.options_text})} unless variant.options_text.blank?
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
-
display_name += " (#{variant.options_text})" unless variant.options_text.blank?
|
17
|
-
|
18
|
-
line_item.errors[:quantity] << Spree.t(
|
19
|
-
:selected_quantity_not_available,
|
20
|
-
item: display_name.inspect
|
21
|
-
)
|
16
|
+
line_item.errors[:quantity] << Spree.t(:selected_quantity_not_available, :scope => :order_populator, :item => display_name.inspect)
|
17
|
+
end
|
22
18
|
end
|
23
19
|
end
|
24
20
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Spree
|
2
|
+
module Stock
|
3
|
+
class ContentItem
|
4
|
+
attr_accessor :inventory_unit, :state
|
5
|
+
|
6
|
+
def initialize(inventory_unit, state = :on_hand)
|
7
|
+
@inventory_unit = inventory_unit
|
8
|
+
@state = state
|
9
|
+
end
|
10
|
+
|
11
|
+
def variant
|
12
|
+
inventory_unit.variant
|
13
|
+
end
|
14
|
+
|
15
|
+
def weight
|
16
|
+
variant.weight * quantity
|
17
|
+
end
|
18
|
+
|
19
|
+
def line_item
|
20
|
+
inventory_unit.line_item
|
21
|
+
end
|
22
|
+
|
23
|
+
def on_hand?
|
24
|
+
state.to_s == "on_hand"
|
25
|
+
end
|
26
|
+
|
27
|
+
def backordered?
|
28
|
+
state.to_s == "backordered"
|
29
|
+
end
|
30
|
+
|
31
|
+
def price
|
32
|
+
variant.price
|
33
|
+
end
|
34
|
+
|
35
|
+
def amount
|
36
|
+
price * quantity
|
37
|
+
end
|
38
|
+
|
39
|
+
def quantity
|
40
|
+
# Since inventory units don't have a quantity,
|
41
|
+
# make this always 1 for now, leaving ourselves
|
42
|
+
# open to a different possibility in the future,
|
43
|
+
# but this massively simplifies things for now
|
44
|
+
1
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
@@ -1,10 +1,17 @@
|
|
1
1
|
module Spree
|
2
2
|
module Stock
|
3
3
|
class Coordinator
|
4
|
-
attr_reader :order
|
4
|
+
attr_reader :order, :inventory_units
|
5
5
|
|
6
|
-
def initialize(order)
|
6
|
+
def initialize(order, inventory_units = nil)
|
7
7
|
@order = order
|
8
|
+
@inventory_units = inventory_units || InventoryUnitBuilder.new(order).units
|
9
|
+
end
|
10
|
+
|
11
|
+
def shipments
|
12
|
+
packages.map do |package|
|
13
|
+
package.to_shipment.tap { |s| s.address = order.ship_address }
|
14
|
+
end
|
8
15
|
end
|
9
16
|
|
10
17
|
def packages
|
@@ -24,9 +31,9 @@ module Spree
|
|
24
31
|
# Returns an array of Package instances
|
25
32
|
def build_packages(packages = Array.new)
|
26
33
|
StockLocation.active.each do |stock_location|
|
27
|
-
next unless stock_location.stock_items.where(:variant_id =>
|
34
|
+
next unless stock_location.stock_items.where(:variant_id => inventory_units.map(&:variant_id)).exists?
|
28
35
|
|
29
|
-
packer = build_packer(stock_location,
|
36
|
+
packer = build_packer(stock_location, inventory_units)
|
30
37
|
packages += packer.packages
|
31
38
|
end
|
32
39
|
packages
|
@@ -34,7 +41,7 @@ module Spree
|
|
34
41
|
|
35
42
|
private
|
36
43
|
def prioritize_packages(packages)
|
37
|
-
prioritizer = Prioritizer.new(
|
44
|
+
prioritizer = Prioritizer.new(inventory_units, packages)
|
38
45
|
prioritizer.prioritized_packages
|
39
46
|
end
|
40
47
|
|
@@ -46,8 +53,8 @@ module Spree
|
|
46
53
|
packages
|
47
54
|
end
|
48
55
|
|
49
|
-
def build_packer(stock_location,
|
50
|
-
Packer.new(stock_location,
|
56
|
+
def build_packer(stock_location, inventory_units)
|
57
|
+
Packer.new(stock_location, inventory_units, splitters(stock_location))
|
51
58
|
end
|
52
59
|
|
53
60
|
def splitters(stock_location)
|
@@ -35,7 +35,7 @@ module Spree
|
|
35
35
|
# If the rate's zone matches the order's zone, a positive adjustment will be applied.
|
36
36
|
# If the rate is from the default tax zone, then a negative adjustment will be applied.
|
37
37
|
# See the tests in shipping_rate_spec.rb for an example of this.d
|
38
|
-
rate.zone ==
|
38
|
+
rate.zone == order.tax_zone || rate.zone.default_tax?
|
39
39
|
end
|
40
40
|
end
|
41
41
|
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Spree
|
2
|
+
module Stock
|
3
|
+
class InventoryUnitBuilder
|
4
|
+
def initialize(order)
|
5
|
+
@order = order
|
6
|
+
end
|
7
|
+
|
8
|
+
def units
|
9
|
+
@order.line_items.flat_map do |line_item|
|
10
|
+
line_item.quantity.times.map do |i|
|
11
|
+
@order.inventory_units.build(
|
12
|
+
pending: true,
|
13
|
+
variant: line_item.variant,
|
14
|
+
line_item: line_item
|
15
|
+
)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -1,53 +1,50 @@
|
|
1
1
|
module Spree
|
2
2
|
module Stock
|
3
3
|
class Package
|
4
|
-
|
5
|
-
|
6
|
-
attr_reader :stock_location, :order, :contents
|
4
|
+
attr_reader :stock_location, :contents
|
7
5
|
attr_accessor :shipping_rates
|
8
6
|
|
9
|
-
def initialize(stock_location,
|
7
|
+
def initialize(stock_location, contents=[])
|
10
8
|
@stock_location = stock_location
|
11
|
-
@order = order
|
12
9
|
@contents = contents
|
13
10
|
@shipping_rates = Array.new
|
14
11
|
end
|
15
12
|
|
16
|
-
def add(
|
17
|
-
contents << ContentItem.new(
|
13
|
+
def add(inventory_unit, state = :on_hand)
|
14
|
+
contents << ContentItem.new(inventory_unit, state) unless find_item(inventory_unit)
|
15
|
+
end
|
16
|
+
|
17
|
+
def add_multiple(inventory_units, state = :on_hand)
|
18
|
+
inventory_units.each { |inventory_unit| add(inventory_unit, state) }
|
19
|
+
end
|
20
|
+
|
21
|
+
def remove(inventory_unit)
|
22
|
+
item = find_item(inventory_unit)
|
23
|
+
@contents -= [item] if item
|
18
24
|
end
|
19
25
|
|
20
26
|
def weight
|
21
|
-
contents.sum
|
27
|
+
contents.sum(&:weight)
|
22
28
|
end
|
23
29
|
|
24
30
|
def on_hand
|
25
|
-
contents.select
|
31
|
+
contents.select(&:on_hand?)
|
26
32
|
end
|
27
33
|
|
28
34
|
def backordered
|
29
|
-
contents.select
|
35
|
+
contents.select(&:backordered?)
|
30
36
|
end
|
31
37
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
item.state == state &&
|
38
|
-
(line_item.nil? || line_item == item.line_item)
|
39
|
-
end.first
|
38
|
+
def find_item(inventory_unit, state = nil)
|
39
|
+
contents.detect do |item|
|
40
|
+
item.inventory_unit == inventory_unit &&
|
41
|
+
(!state || item.state.to_s == state.to_s)
|
42
|
+
end
|
40
43
|
end
|
41
44
|
|
42
|
-
def quantity(state=nil)
|
43
|
-
|
44
|
-
|
45
|
-
on_hand.sum { |item| item.quantity }
|
46
|
-
when :backordered
|
47
|
-
backordered.sum { |item| item.quantity }
|
48
|
-
else
|
49
|
-
contents.sum { |item| item.quantity }
|
50
|
-
end
|
45
|
+
def quantity(state = nil)
|
46
|
+
matched_contents = state.nil? ? contents : contents.select { |c| c.state.to_s == state.to_s }
|
47
|
+
matched_contents.map(&:quantity).sum
|
51
48
|
end
|
52
49
|
|
53
50
|
def empty?
|
@@ -55,7 +52,7 @@ module Spree
|
|
55
52
|
end
|
56
53
|
|
57
54
|
def currency
|
58
|
-
|
55
|
+
#TODO calculate from first variant?
|
59
56
|
end
|
60
57
|
|
61
58
|
def shipping_categories
|
@@ -67,32 +64,22 @@ module Spree
|
|
67
64
|
end
|
68
65
|
|
69
66
|
def inspect
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
end.join('/')
|
74
|
-
out
|
67
|
+
contents.map do |content_item|
|
68
|
+
"#{content_item.variant.name} #{content_item.state}"
|
69
|
+
end.join(' / ')
|
75
70
|
end
|
76
71
|
|
77
72
|
def to_shipment
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
unit.order = order
|
89
|
-
unit.variant = item.variant
|
90
|
-
unit.line_item = item.line_item
|
91
|
-
unit.state = item.state.to_s
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
shipment
|
73
|
+
# At this point we should only have one content item per inventory unit
|
74
|
+
# across the entire set of inventory units to be shipped, which has been
|
75
|
+
# taken care of by the Prioritizer
|
76
|
+
contents.each { |content_item| content_item.inventory_unit.state = content_item.state.to_s }
|
77
|
+
|
78
|
+
Spree::Shipment.new(
|
79
|
+
stock_location: stock_location,
|
80
|
+
shipping_rates: shipping_rates,
|
81
|
+
inventory_units: contents.map(&:inventory_unit)
|
82
|
+
)
|
96
83
|
end
|
97
84
|
end
|
98
85
|
end
|
@@ -1,11 +1,11 @@
|
|
1
1
|
module Spree
|
2
2
|
module Stock
|
3
3
|
class Packer
|
4
|
-
attr_reader :stock_location, :
|
4
|
+
attr_reader :stock_location, :inventory_units, :splitters
|
5
5
|
|
6
|
-
def initialize(stock_location,
|
6
|
+
def initialize(stock_location, inventory_units, splitters=[Splitter::Base])
|
7
7
|
@stock_location = stock_location
|
8
|
-
@
|
8
|
+
@inventory_units = inventory_units
|
9
9
|
@splitters = splitters
|
10
10
|
end
|
11
11
|
|
@@ -18,17 +18,19 @@ module Spree
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def default_package
|
21
|
-
package = Package.new(stock_location
|
22
|
-
|
23
|
-
|
24
|
-
|
21
|
+
package = Package.new(stock_location)
|
22
|
+
inventory_units.group_by(&:variant).each do |variant, variant_inventory_units|
|
23
|
+
units = variant_inventory_units.clone
|
24
|
+
if variant.should_track_inventory?
|
25
|
+
next unless stock_location.stock_item(variant)
|
25
26
|
|
26
|
-
on_hand, backordered = stock_location.fill_status(
|
27
|
-
package.
|
28
|
-
package.
|
27
|
+
on_hand, backordered = stock_location.fill_status(variant, units.count)
|
28
|
+
package.add_multiple units.slice!(0, on_hand), :on_hand if on_hand > 0
|
29
|
+
package.add_multiple units.slice!(0, backordered), :backordered if backordered > 0
|
29
30
|
else
|
30
|
-
package.
|
31
|
+
package.add_multiple units
|
31
32
|
end
|
33
|
+
|
32
34
|
end
|
33
35
|
package
|
34
36
|
end
|