Class: Spree::Promotion::Actions::CreateLineItems
- Inherits:
-
Spree::PromotionAction
- Object
- Spree::PromotionAction
- Spree::Promotion::Actions::CreateLineItems
- Defined in:
- app/models/spree/promotion/actions/create_line_items.rb
Instance Method Summary collapse
-
#item_available?(item) ⇒ Boolean
Checks that there’s enough stock to add the line item to the order.
-
#perform(options = {}) ⇒ Object
Adds a line item to the Order if the promotion is eligible.
-
#revert(options = {}) ⇒ Object
Called by promotion handler when a promotion is removed This will find any line item matching the ones defined in the PromotionAction and remove the same quantity as was added by the PromotionAction.
Methods inherited from Spree::PromotionAction
#free_shipping?, #human_description, #human_name, #key
Instance Method Details
#item_available?(item) ⇒ Boolean
Checks that there’s enough stock to add the line item to the order
81 82 83 84 |
# File 'app/models/spree/promotion/actions/create_line_items.rb', line 81 def item_available?(item) quantifier = Spree::Stock::Quantifier.new(item.variant) quantifier.can_supply? item.quantity end |
#perform(options = {}) ⇒ Object
Adds a line item to the Order if the promotion is eligible
This doesn’t play right with Add to Cart events because at the moment the item was added to cart the promo may not be eligible. However it might become eligible as the order gets updated.
e.g.
- A promo adds a line item to cart if order total greater then $30
- Customer add 1 item of $10 to cart
- This action shouldn't perform because the order is not eligible
- Customer increases item quantity to 5 (order total goes to $50)
- Now the order is eligible for the promo and the action should perform
Another complication is when the same line item created by the promo is also added to cart on a separate action.
e.g.
- Promo adds 1 item A to cart if order total greater then $30
- Customer add 2 items B to cart, current order total is $40
- This action performs adding item A to cart since order is eligible
- Customer changes his mind and updates item B quantity to 1
- At this point order is no longer eligible and one might expect
that item A should be removed
It doesn’t remove items from the order here because there’s no way it can know whether that item was added via this promo action or if it was manually populated somewhere else. In that case the item needs to be manually removed from the order by the customer
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'app/models/spree/promotion/actions/create_line_items.rb', line 41 def perform( = {}) order = [:order] return unless eligible? order action_taken = false promotion_action_line_items.each do |item| current_quantity = order.quantity_of(item.variant) next unless current_quantity < item.quantity && item_available?(item) line_item = Spree::Dependencies.cart_add_item_service.constantize.call(order: order, variant: item.variant, quantity: item.quantity - current_quantity).value action_taken = true if line_item.try(:valid?) end action_taken end |
#revert(options = {}) ⇒ Object
Called by promotion handler when a promotion is removed This will find any line item matching the ones defined in the PromotionAction and remove the same quantity as was added by the PromotionAction. Should help to prevent some of cases listed above the #perform method
62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'app/models/spree/promotion/actions/create_line_items.rb', line 62 def revert( = {}) order = [:order] return if eligible?(order) action_taken = false promotion_action_line_items.each do |item| line_item = order.find_line_item_by_variant(item.variant) next unless line_item.present? Spree::Dependencies.cart_remove_item_service.constantize.call(order: order, variant: item.variant, quantity: (item.quantity || 1)) action_taken = true end action_taken end |