Skip to main content

Overview

In this guide we will show you how to create custom promotion rules and actions in Spree.

Custom Promotion Actions

Ensure you have the following directory structure:
mkdir -p app/models/spree/promotion/actions
Create a new file in app/models/spree/promotion/actions/ directory
touch app/models/spree/promotion/actions/my_promotion_action.rb
Implement your custom logic in the perform method.
module Spree
  module Promotion
    module Actions
      class MyPromotionAction < Spree::PromotionAction
        def perform(options={})
          # Implement your custom logic here
        end
      end
    end
  end
end
This class needs to inherit from Spree::PromotionAction model.
You can access promotion information using the promotion method within any Spree::PromotionAction.
Register the new action with Spree. Open config/initializers/spree.rb and add the following line:
Rails.application.config.after_initialize do
  Rails.application.config.spree.promotions.actions << Spree::Promotion::Actions::MyPromotionAction
end
Once this has been registered, it will be available within Spree’s interface.
To provide translations for the interface, you will need to define them within your locale file. For instance, to define English translations for your new promotion action, use this code within config/locales/en.yml:
  en:
    spree:
      promotion_action_types:
        my_promotion_action:
          name: My Promotion Action
          description: Performs my promotion action.
After making these changes, restart your application. Your custom promotion action will now be available within Spree’s admin interface, ready for use in your promotions.

Custom Promotion Rules

Ensure you have the following directory structure:
mkdir -p app/models/spree/promotion/rules
Create a new file in app/models/spree/promotion/rules/ directory:
touch app/models/spree/promotion/rules/my_promotion_rule.rb
Implement your logic within this class as shown below:
module Spree
  class Promotion
    module Rules
      class MyPromotionRule < Spree::PromotionRule
        def applicable?(promotable)
          promotable.is_a?(Spree::Order)
        end

        def eligible?(order, options = {})
          # Your custom eligibility logic here
        end

        def actionable?(line_item)
          # Your custom actionability logic here
        end
      end
    end
  end
end
This class needs to inherit from Spree::PromotionRule model.
The eligible? method should return true or false to indicate if the promotion should be eligible for an order, based on your custom logic. Similarly, define actionable? to evaluate line items against your promotion criteria.
To make your custom rule available, register it within Spree by adding the following block to your config/initializers/spree.rb file:
Rails.application.config.after_initialize do
  Rails.application.config.spree.promotions.rules << Spree::Promotion::Rules::MyPromotionRule
end
This step ensures that your custom rule is recognized and can be utilized within the Spree ecosystem.
Create a partial for your new rule:
touch app/views/spree/admin/promotions/rules/_my_promotion_rule.html.erb
This file can either be simple or complex based on whether your rule requires parameters for configuration.For guidance, refer to existing rule partials in Spree’s backend sources to understand how to structure this file.
To display your rule within the Spree admin interface, define its name and description in your locale files. For English, edit config/locales/en.yml and add:
en:
  spree:
    promotion_rule_types:
      my_promotion_rule:
        name: "My Promotion Rule"
        description: "Custom rule for my promotion"
After making these changes, restart your application. Your custom promotion rule will now be available within Spree’s admin interface, ready for use in your promotions.