spree_limit_order_quantity 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +23 -0
  3. data/Gemfile +3 -0
  4. data/LICENSE +673 -0
  5. data/README.md +54 -0
  6. data/app/controllers/spree_limit_order_quantity/checkout_controller_decorator.rb +33 -0
  7. data/app/controllers/spree_limit_order_quantity/line_items_controller_decorator.rb +54 -0
  8. data/app/decorators/spree/core/controller_helpers/strong_parameters_loq_decorator.rb +21 -0
  9. data/app/models/spree_limit_order_quantity/product_decorator.rb +13 -0
  10. data/app/models/spree_limit_order_quantity/variant_decorator.rb +24 -0
  11. data/app/overrides/spree/admin/variants/edit/add_order_quantity_limits_form.html.erb.deface +2 -0
  12. data/app/views/spree/admin/products/form/_limit_product_quantity_settings.html.erb +3 -0
  13. data/app/views/spree_limit_order_quantity/admin/shared/_limit_quantity_settings.html.erb +19 -0
  14. data/bin/rails +8 -0
  15. data/config/locales/activerecord.en.yml +13 -0
  16. data/config/locales/activerecord.ja.yml +13 -0
  17. data/config/locales/en.yml +10 -0
  18. data/config/locales/ja.yml +10 -0
  19. data/db/migrate/20250505025922_add_order_quantity_limits_to_spree_variants.rb +6 -0
  20. data/lib/generators/spree_limit_order_quantity/install/install_generator.rb +20 -0
  21. data/lib/spree_limit_order_quantity/engine.rb +25 -0
  22. data/lib/spree_limit_order_quantity/master_variant_quantity_checker.rb +56 -0
  23. data/lib/spree_limit_order_quantity/order_quantity_checker.rb +54 -0
  24. data/lib/spree_limit_order_quantity/version.rb +7 -0
  25. data/lib/spree_limit_order_quantity.rb +7 -0
  26. data/spec/spec_helper.rb +93 -0
  27. data/spree_limit_order_quantity.gemspec +34 -0
  28. metadata +168 -0
data/README.md ADDED
@@ -0,0 +1,54 @@
1
+ # Spree Limit order quantity
2
+
3
+ This is a Spree extension that allows store administrators to set **minimum** and **maximum** quantity limits per product or variant for each order. This helps control how many units of a product or variant a customer can add to their cart or order.
4
+
5
+ ## Features
6
+
7
+ - Set **minimum** and **maximum** quantity per order for each product.
8
+ - Override those limits at the **variant** level.
9
+ - Enforce quantity limits in the cart and checkout process.
10
+ - Edit these limits directly from the admin panel (Product or Variant edit pages).
11
+
12
+ ## Installation
13
+
14
+ 1. Add this extension to your Gemfile with this line:
15
+
16
+ ```ruby
17
+ gem 'spree_limit_order_quantity', github: 'be-agile/spree_limit_order_quantity'
18
+ ```
19
+
20
+ 2. Then bundle install:
21
+
22
+ ```bash
23
+ bundle install
24
+ ```
25
+
26
+ 3. Run the install generator
27
+
28
+ ```ruby
29
+ bundle exec rails g spree_limit_order_quantity:install
30
+ ```
31
+
32
+ 4. Run migrations:
33
+
34
+ ```bash
35
+ rails db:migrate
36
+ ```
37
+
38
+ ## Validation Behavior
39
+
40
+ During add-to-cart and checkout:
41
+
42
+ - If the quantity is less than the minimum or greater than the maximum, the system will show an error and prevent the action.
43
+
44
+ - Limits are applied per line item per order.
45
+
46
+ ## License
47
+
48
+ This extension is available as open source under the terms of either:
49
+ * [GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later)](https://www.gnu.org/licenses/agpl-3.0.en.html)
50
+ * [BSD 3-Clause License](https://opensource.org/licenses/BSD-3-Clause)
51
+
52
+ ## Credits
53
+
54
+ [be agile Co., Ltd.](https://be-agile.jp/)
@@ -0,0 +1,33 @@
1
+ module SpreeLimitOrderQuantity
2
+ module CheckoutControllerDecorator
3
+ def self.prepended(base)
4
+ base.before_action :validate_master_variant_limits, only: [ :edit, :update ]
5
+ end
6
+
7
+ private
8
+
9
+ def validate_master_variant_limits
10
+ @order.line_items.group_by { |li| li.variant.product }.each do |product, line_items|
11
+ next unless should_check_master_limits?(product)
12
+
13
+ total_quantity = line_items.sum(&:quantity)
14
+ checker = MasterVariantQuantityChecker.new(product, total_quantity)
15
+
16
+ unless checker.valid?
17
+ flash[:error] = checker.error_message
18
+ redirect_to spree.product_path(product, order_token: @order.token)
19
+ return
20
+ end
21
+ end
22
+ end
23
+
24
+ def should_check_master_limits?(product)
25
+ master_variant = product.master
26
+ master_variant.min_order_quantity.present? || master_variant.max_order_quantity.present?
27
+ end
28
+ end
29
+ end
30
+
31
+ if Spree::CheckoutController.included_modules.exclude?(SpreeLimitOrderQuantity::CheckoutControllerDecorator)
32
+ Spree::CheckoutController.prepend(SpreeLimitOrderQuantity::CheckoutControllerDecorator)
33
+ end
@@ -0,0 +1,54 @@
1
+ module SpreeLimitOrderQuantity
2
+ module LineItemsControllerDecorator
3
+ def self.prepended(base)
4
+ base.before_action :validate_order_item_quantity, only: [ :update, :create ]
5
+ end
6
+
7
+ private
8
+
9
+ def validate_order_item_quantity
10
+ initialize_quantity_validation
11
+ return if @quantity_checker.valid?
12
+
13
+ handle_quantity_error
14
+ end
15
+
16
+ def initialize_quantity_validation
17
+ variant = @variant || @line_item&.variant
18
+ order = @order || current_order(create_order_if_necessary: true)
19
+ @quantity_checker = OrderQuantityChecker.new(order, variant, quantity: determine_order_item_quantity)
20
+ @quantity_checker.quantity += @quantity_checker.calculate_quantity if action_name == 'create'
21
+ end
22
+
23
+ def handle_quantity_error
24
+ flash_message = @quantity_checker.validation_error_messages.to_sentence
25
+ return product_quantity_error_response_stream(flash_message) if request.format.turbo_stream?
26
+
27
+ flash[:error] = flash_message
28
+ redirect_to spree.cart_path(order_token: order_token)
29
+ end
30
+
31
+ def product_quantity_error_response_stream(flash_message)
32
+ @order ||= @quantity_checker.order
33
+ load_line_items
34
+ template = "spree/line_items/#{action_name}"
35
+
36
+ # Render the Turbo Stream without flash message for updating line items
37
+ line_item_update_stream = render_to_string(template: template, formats: [ :turbo_stream ])
38
+
39
+ # Render the Turbo Stream for displaying the flash message
40
+ flash.now[:error] = flash_message
41
+ flash_message_stream = render_to_string(template: template, formats: [ :turbo_stream ])
42
+
43
+ render turbo_stream: [ flash_message_stream, line_item_update_stream ]
44
+ end
45
+
46
+ def determine_order_item_quantity
47
+ (params[:quantity].presence || line_item_params[:quantity].presence || 1).to_i
48
+ end
49
+ end
50
+ end
51
+
52
+ if Spree::LineItemsController.included_modules.exclude?(SpreeLimitOrderQuantity::LineItemsControllerDecorator)
53
+ Spree::LineItemsController.prepend(SpreeLimitOrderQuantity::LineItemsControllerDecorator)
54
+ end
@@ -0,0 +1,21 @@
1
+ module Spree
2
+ module Core
3
+ module ControllerHelpers
4
+ module StrongParametersLoqDecorator
5
+ def permitted_variant_attributes
6
+ super + [ :min_order_quantity, :max_order_quantity ]
7
+ end
8
+
9
+ # @gem-override spree_core-5.3.6/lib/spree/core/controller_helpers/strong_parameters.rb#permitted_product_attributes
10
+ # @see https://github.com/be-agile/giga-repeat/commit/051fe2e2c01d36f5c85cee7f2033e8f90a7b3e7c
11
+ # 注文数量制限の min/max を許可属性に追加する。
12
+ def permitted_product_attributes
13
+ super + [ :min_order_quantity, :max_order_quantity ]
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ ::Spree::Core::ControllerHelpers::StrongParameters.prepend(
20
+ Spree::Core::ControllerHelpers::StrongParametersLoqDecorator
21
+ )
@@ -0,0 +1,13 @@
1
+ module SpreeLimitOrderQuantity
2
+ module ProductDecorator
3
+ def self.prepended(base)
4
+ [ :min_order_quantity, :max_order_quantity ].each do |method_name|
5
+ base.delegate method_name, :"#{method_name}=", to: :default_variant
6
+ end
7
+ end
8
+ end
9
+ end
10
+
11
+ if Spree::Product.included_modules.exclude?(SpreeLimitOrderQuantity::ProductDecorator)
12
+ Spree::Product.prepend(SpreeLimitOrderQuantity::ProductDecorator)
13
+ end
@@ -0,0 +1,24 @@
1
+ module SpreeLimitOrderQuantity
2
+ module VariantDecorator
3
+ def self.prepended(base)
4
+ base.validates :min_order_quantity, numericality: { only_integer: true, greater_than_or_equal_to: 1 }, if: -> { !min_order_quantity.nil? }
5
+ base.validates :max_order_quantity, numericality: { only_integer: true, greater_than_or_equal_to: 1 }, if: -> { !max_order_quantity.nil? }
6
+ base.validate :validate_min_max_order_quantity
7
+ end
8
+
9
+ private
10
+
11
+ def validate_min_max_order_quantity
12
+ if !min_order_quantity.nil? && !max_order_quantity.nil? && min_order_quantity > max_order_quantity
13
+ errors.add(
14
+ :base,
15
+ I18n.t('activerecord.errors.models.spree/variant.attributes.max_order_quantity.greater_than_min_order_quantity')
16
+ )
17
+ end
18
+ end
19
+ end
20
+ end
21
+
22
+ if Spree::Variant.included_modules.exclude?(SpreeLimitOrderQuantity::VariantDecorator)
23
+ Spree::Variant.prepend(SpreeLimitOrderQuantity::VariantDecorator)
24
+ end
@@ -0,0 +1,2 @@
1
+ <!-- insert_after "erb[loud]:contains('spree/admin/variants/form/inventory')" -->
2
+ <%= render 'spree_limit_order_quantity/admin/shared/limit_quantity_settings', f: f %>
@@ -0,0 +1,3 @@
1
+ <%= f.fields_for :master, @product.master do |vf| %>
2
+ <%= render 'spree_limit_order_quantity/admin/shared/limit_quantity_settings', f: vf %>
3
+ <% end %>
@@ -0,0 +1,19 @@
1
+ <div class="card mb-4" id="limit-quantity-settings-card">
2
+ <div class="card-header">
3
+ <h5 class="card-title">
4
+ <%= Spree.t('admin.limit_product_quantity_settings') %>
5
+ </h5>
6
+ </div>
7
+ <div class="card-body">
8
+
9
+ <% [ :min_order_quantity, :max_order_quantity ].each do |field| %>
10
+ <div class="form-group d-flex align-items-center">
11
+ <%= f.label(field, class: 'col-form-label text-nowrap mr-3') %>
12
+ <div class="flex-grow-1">
13
+ <%= f.number_field(field, class: 'form-control', min: 1) %>
14
+ </div>
15
+ </div>
16
+ <% end %>
17
+
18
+ </div>
19
+ </div>
data/bin/rails ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+ # This command will automatically be run when you run "rails" from the root of your extension
3
+
4
+ ENGINE_ROOT = File.expand_path('../..', __FILE__)
5
+ ENGINE_PATH = File.expand_path('../../lib/spree_limit_order_quantity/engine', __FILE__)
6
+
7
+ require 'rails/all'
8
+ require 'rails/engine/commands'
@@ -0,0 +1,13 @@
1
+ en:
2
+ activerecord:
3
+ attributes:
4
+ spree/variant:
5
+ min_order_quantity: Minimum Order Quantity
6
+ max_order_quantity: Maximum Order Quantity
7
+
8
+ errors:
9
+ models:
10
+ spree/variant:
11
+ attributes:
12
+ max_order_quantity:
13
+ greater_than_min_order_quantity: "The order quantity must be greater than or equal to the minimum quantity"
@@ -0,0 +1,13 @@
1
+ ja:
2
+ activerecord:
3
+ attributes:
4
+ spree/variant:
5
+ min_order_quantity: 注文時の最低数量
6
+ max_order_quantity: 注文時の最大数量
7
+
8
+ errors:
9
+ models:
10
+ spree/variant:
11
+ attributes:
12
+ max_order_quantity:
13
+ greater_than_min_order_quantity: "注文数量は最小数量以上でなければなりません"
@@ -0,0 +1,10 @@
1
+ en:
2
+ spree:
3
+ storefront:
4
+ line_item:
5
+ max_order_quantity_error: "You can only purchase up to %{max_quantity} of %{product_name}."
6
+ min_order_quantity_error: "Please order at least %{min_quantity} of %{product_name}."
7
+ master_max_order_quantity_error: "You can purchase up to a maximum of %{max_quantity} units in total for all variations of %{product_name}."
8
+ master_min_order_quantity_error: "Please order at least %{min_quantity} units in total for all variations of %{product_name}."
9
+ admin:
10
+ limit_product_quantity_settings: "Limit Product Quantity Settings"
@@ -0,0 +1,10 @@
1
+ ja:
2
+ spree:
3
+ storefront:
4
+ line_item:
5
+ max_order_quantity_error: "%{product_name}は最大%{max_quantity}個まで購入できます。"
6
+ min_order_quantity_error: "%{product_name}は最低%{min_quantity}個以上注文してください。"
7
+ master_max_order_quantity_error: "%{product_name}の全バリエーション合計は最大%{max_quantity}個まで購入できます。"
8
+ master_min_order_quantity_error: "%{product_name}の全バリエーション合計は最低%{min_quantity}個以上注文してください。"
9
+ admin:
10
+ limit_product_quantity_settings: "注文数量の制限"
@@ -0,0 +1,6 @@
1
+ class AddOrderQuantityLimitsToSpreeVariants < ActiveRecord::Migration[8.0]
2
+ def change
3
+ add_column :spree_variants, :min_order_quantity, :integer, null: true
4
+ add_column :spree_variants, :max_order_quantity, :integer, null: true
5
+ end
6
+ end
@@ -0,0 +1,20 @@
1
+ module SpreeLimitOrderQuantity
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+ class_option :migrate, type: :boolean, default: true
5
+
6
+ def add_migrations
7
+ run 'bundle exec rake railties:install:migrations FROM=spree_limit_order_quantity'
8
+ end
9
+
10
+ def run_migrations
11
+ run_migrations = options[:migrate] || [ '', 'y', 'Y' ].include?(ask('Would you like to run the migrations now? [Y/n]'))
12
+ if run_migrations
13
+ run 'bin/rails db:migrate'
14
+ else
15
+ puts 'Skipping rails db:migrate, don\'t forget to run it!'
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,25 @@
1
+ module SpreeLimitOrderQuantity
2
+ class Engine < Rails::Engine
3
+ require 'spree/core'
4
+ isolate_namespace Spree
5
+ engine_name 'spree_limit_order_quantity'
6
+
7
+ def self.activate
8
+ Dir.glob(File.join(File.dirname(__FILE__), '../../app/**/*_decorator*.rb')) do |c|
9
+ Rails.configuration.cache_classes ? require(c) : load(c)
10
+ end
11
+ end
12
+
13
+ config.after_initialize do
14
+ Rails.application.config.spree_admin.product_form_partials << 'spree/admin/products/form/limit_product_quantity_settings'
15
+ end
16
+
17
+ initializer 'spree_limit_order_quantity.autoloader' do |app|
18
+ if Rails.autoloaders.zeitwerk_enabled?
19
+ Rails.autoloaders.main.ignore("#{root}/app/overrides")
20
+ end
21
+ end
22
+
23
+ config.to_prepare(&method(:activate).to_proc)
24
+ end
25
+ end
@@ -0,0 +1,56 @@
1
+ module SpreeLimitOrderQuantity
2
+ class MasterVariantQuantityChecker
3
+ attr_accessor :product, :total_quantity
4
+
5
+ def initialize(product, total_quantity)
6
+ @product = product
7
+ @total_quantity = total_quantity
8
+ end
9
+
10
+ def valid?
11
+ max_quantity_valid? && min_quantity_valid?
12
+ end
13
+
14
+ def max_quantity_valid?
15
+ return true if master_variant.max_order_quantity.nil?
16
+
17
+ @total_quantity <= master_variant.max_order_quantity
18
+ end
19
+
20
+ def min_quantity_valid?
21
+ return true if master_variant.min_order_quantity.nil?
22
+
23
+ @total_quantity >= master_variant.min_order_quantity
24
+ end
25
+
26
+ def should_check_limits?
27
+ master_variant.min_order_quantity.present? || master_variant.max_order_quantity.present?
28
+ end
29
+
30
+ def error_message
31
+ return nil if valid?
32
+
33
+ product_name = @product.name
34
+
35
+ if !max_quantity_valid?
36
+ Spree.t(
37
+ "storefront.line_item.master_max_order_quantity_error",
38
+ product_name: product_name,
39
+ max_quantity: master_variant.max_order_quantity
40
+ )
41
+ elsif !min_quantity_valid?
42
+ Spree.t(
43
+ "storefront.line_item.master_min_order_quantity_error",
44
+ product_name: product_name,
45
+ min_quantity: master_variant.min_order_quantity
46
+ )
47
+ end
48
+ end
49
+
50
+ private
51
+
52
+ def master_variant
53
+ @master_variant ||= @product.master
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,54 @@
1
+ module SpreeLimitOrderQuantity
2
+ class OrderQuantityChecker
3
+ attr_accessor :order, :variant, :quantity
4
+
5
+ def initialize(order, variant, quantity: nil)
6
+ @order = order
7
+ @variant = variant
8
+ @quantity = quantity.nil? ? calculate_quantity : quantity
9
+ end
10
+
11
+ def valid?
12
+ max_quantity_valid? && min_quantity_valid?
13
+ end
14
+
15
+ def max_quantity_valid?
16
+ return true if @variant.max_order_quantity.nil?
17
+
18
+ @quantity <= @variant.max_order_quantity
19
+ end
20
+
21
+ def min_quantity_valid?
22
+ return true if @variant.min_order_quantity.nil?
23
+
24
+ @quantity >= @variant.min_order_quantity
25
+ end
26
+
27
+ def calculate_quantity
28
+ @order.line_items.where(variant: @variant).sum(:quantity).to_i
29
+ end
30
+
31
+ def validation_error_messages
32
+ messages = []
33
+ product_name = @variant.name
34
+
35
+ unless max_quantity_valid?
36
+ messages << Spree.t(
37
+ "storefront.line_item.max_order_quantity_error",
38
+ product_name: product_name,
39
+ max_quantity: @variant.max_order_quantity
40
+ )
41
+ end
42
+
43
+ unless min_quantity_valid?
44
+ messages << Spree.t(
45
+ "storefront.line_item.min_order_quantity_error",
46
+ product_name: product_name,
47
+ min_quantity: @variant.min_order_quantity
48
+ )
49
+ end
50
+
51
+ messages
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,7 @@
1
+ module SpreeLimitOrderQuantity
2
+ VERSION = '1.0.0'.freeze
3
+
4
+ def gem_version
5
+ Gem::Version.new(VERSION)
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ require 'spree_core'
2
+ require 'spree_extension'
3
+ require 'spree_limit_order_quantity/engine'
4
+ require 'spree_limit_order_quantity/version'
5
+ require 'spree_limit_order_quantity/order_quantity_checker'
6
+ require 'spree_limit_order_quantity/master_variant_quantity_checker'
7
+ require 'deface'
@@ -0,0 +1,93 @@
1
+ # Run Coverage report
2
+ require 'simplecov'
3
+ SimpleCov.start do
4
+ add_filter 'spec/dummy'
5
+ add_filter 'vendor/'
6
+ add_group 'Controllers', 'app/controllers'
7
+ add_group 'Helpers', 'app/helpers'
8
+ add_group 'Mailers', 'app/mailers'
9
+ add_group 'Models', 'app/models'
10
+ add_group 'Views', 'app/views'
11
+ add_group 'Libraries', 'lib'
12
+ end
13
+
14
+ # Configure Rails Environment
15
+ ENV['RAILS_ENV'] = 'test'
16
+
17
+ require File.expand_path('../../../config/environment.rb', __FILE__)
18
+
19
+ require 'rspec/rails'
20
+ require 'database_cleaner'
21
+ require 'ffaker'
22
+ require 'shoulda/matchers'
23
+ require 'rspec/active_model/mocks'
24
+
25
+ # Requires supporting ruby files with custom matchers and macros, etc,
26
+ # in spec/support/ and its subdirectories.
27
+ Dir[File.join(File.dirname(__FILE__), 'support/**/*.rb')].each { |f| require f }
28
+
29
+ # Requires factories defined in spree_core
30
+ require 'spree/testing_support/factories'
31
+ require 'spree/testing_support/controller_requests'
32
+ require 'spree/testing_support/authorization_helpers'
33
+ require 'spree/testing_support/url_helpers'
34
+
35
+ RSpec.configure do |config|
36
+ config.include FactoryGirl::Syntax::Methods
37
+
38
+ # == URL Helpers
39
+ #
40
+ # Allows access to Spree's routes in specs:
41
+ #
42
+ # visit spree.admin_path
43
+ # current_path.should eql(spree.products_path)
44
+ config.include Spree::TestingSupport::UrlHelpers
45
+
46
+ # == Mock Framework
47
+ #
48
+ # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
49
+ #
50
+ # config.mock_with :mocha
51
+ # config.mock_with :flexmock
52
+ # config.mock_with :rr
53
+ config.mock_with :rspec
54
+ config.color = true
55
+
56
+ # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
57
+ config.fixture_path = "#{::Rails.root}/spec/fixtures"
58
+
59
+ # Capybara javascript drivers require transactional fixtures set to false, and we use DatabaseCleaner
60
+ # to cleanup after each test instead. Without transactional fixtures set to false the records created
61
+ # to setup a test will be unavailable to the browser, which runs under a seperate server instance.
62
+ config.use_transactional_fixtures = false
63
+ config.include Spree::Core::Engine.routes.url_helpers
64
+
65
+ # Ensure Suite is set to use transactions for speed.
66
+ config.before :suite do
67
+ DatabaseCleaner.strategy = :transaction
68
+ DatabaseCleaner.clean_with :truncation
69
+ end
70
+
71
+ # Before each spec check if it is a Javascript test and switch between using database transactions or not where necessary.
72
+ config.before :each do |example|
73
+ DatabaseCleaner.strategy = example.metadata[:js] ? :truncation : :transaction
74
+ DatabaseCleaner.start
75
+ end
76
+
77
+ # After each spec clean the database.
78
+ config.after :each do
79
+ DatabaseCleaner.clean
80
+ end
81
+
82
+ config.fail_fast = ENV['FAIL_FAST'] || false
83
+ config.include Spree::TestingSupport::UrlHelpers, type: :controller
84
+ config.include Spree::TestingSupport::ControllerRequests, type: :controller
85
+ config.infer_spec_type_from_file_location!
86
+ end
87
+
88
+ Shoulda::Matchers.configure do |config|
89
+ config.integrate do |with|
90
+ with.test_framework :rspec
91
+ with.library :rails
92
+ end
93
+ end
@@ -0,0 +1,34 @@
1
+ # encoding: UTF-8
2
+
3
+ lib = File.expand_path('../lib/', __FILE__)
4
+ $LOAD_PATH.unshift lib unless $LOAD_PATH.include?(lib)
5
+
6
+ require 'spree_limit_order_quantity/version'
7
+
8
+ Gem::Specification.new do |s|
9
+ s.platform = Gem::Platform::RUBY
10
+ s.name = 'spree_limit_order_quantity'
11
+ s.version = SpreeLimitOrderQuantity::VERSION
12
+ s.summary = "Limit the minimum and maximum quantity per product or variant per order in Spree"
13
+ s.required_ruby_version = '>= 3.0'
14
+
15
+ s.author = 'be agile Co., Ltd.'
16
+ s.email = 'develop@be-agile.jp'
17
+ s.homepage = 'https://github.com/be-agile/spree_limit_order_quantity'
18
+ s.licenses = ['AGPL-3.0-or-later']
19
+
20
+ s.files = `git ls-files`.split("\n")
21
+ s.require_path = 'lib'
22
+ s.requirements << 'none'
23
+
24
+ s.add_dependency 'spree', '= 5.3.6'
25
+ s.add_dependency 'spree_storefront', '= 5.3.6'
26
+ s.add_dependency 'spree_admin', '= 5.3.6'
27
+ s.add_dependency 'spree_extension', '= 0.1.0'
28
+ s.add_dependency 'deface'
29
+
30
+ s.add_development_dependency 'spree_dev_tools'
31
+
32
+ # @gem-override マーカーの差分確認に使う開発ツール
33
+ s.add_development_dependency 'gem_override_marker'
34
+ end