How can I limit product purchase quantity per customer?

class Campaign
def initialize(condition, *qualifiers)
@condition = (condition.to_s + ‘?’).to_sym
@qualifiers = PostCartAmountQualifier ? : rescue qualifiers.compact
@Anonymous _item_selector = qualifiers.last unless @Anonymous _item_selector
qualifiers.compact.each do |qualifier|
is_multi_select = qualifier.instance_variable_get(:@conditions).is_a?(Array)
if is_multi_select
qualifier.instance_variable_get(:@conditions).each do |nested_q|
@post_amount_qualifier = nested_q if nested_q.is_a?(PostCartAmountQualifier)
@qualifiers << qualifier
end
else
@post_amount_qualifier = qualifier if qualifier.is_a?(PostCartAmountQualifier)
@qualifiers << qualifier
end
end if @qualifiers.empty?
end

def qualifies?(cart)
return true if @qualifiers.empty?
@unmodified_line_items = cart.line_items.map do |item|
new_item = item.dup
new_item.instance_variables.each do |var|
val = item.instance_variable_get(var)
new_item.instance_variable_set(var, val.dup) if val.respond_to?(:dup)
end
new_item
end if @post_amount_qualifier
@qualifiers.send(@condition) do |qualifier|
is_selector = false
if qualifier.is_a?(Selector) || qualifier.instance_variable_get(:@conditions).any? { |q| q.is_a?(Selector) }
is_selector = true
end rescue nil
if is_selector
raise “Missing line item match type” if @Li _match_type.nil?
cart.line_items.send(@li_match_type) { |item| qualifier.match?(item) }
else
qualifier.match?(cart, @Anonymous _item_selector)
end
end
end

def run_with_hooks(cart)
before_run(cart) if respond_to?(:before_run)
run(cart)
after_run(cart)
end

def after_run(cart)
@discount.apply_final_discount if @discount && @discount.respond_to?(:apply_final_discount)
revert_changes(cart) unless @post_amount_qualifier.nil? || @post_amount_qualifier.match?(cart)
end

def revert_changes(cart)
cart.instance_variable_set(:@line_items, @unmodified_line_items)
end
end

class QuantityLimit < Campaign
def initialize(condition, customer_qualifier, cart_qualifier, line_item_selector, limit_by, limit)
super(condition, customer_qualifier, cart_qualifier)
@limit_by = limit_by
@Anonymous _item_selector = line_item_selector
@Per _item_limit = limit
end

def run(cart)
return unless qualifies?(cart)
item_limits = {}
to_delete =
if @Per _item_limit == 0
cart.line_items.delete_if { |item| @Anonymous _item_selector.nil? || @Anonymous _item_selector.match?(item) }
else
cart.line_items.each_with_index do |item, index|
next unless @Anonymous _item_selector.nil? || @Anonymous _item_selector.match?(item)
key = nil
case @limit_by
when :product
key = item.variant.product.id
when :variant
key = item.variant.id
end

if key
item_limits[key] = @Per _item_limit if !item_limits.has_key?(key)
needs_limiting = true if item.quantity > item_limits[key]
needs_deleted = true if item_limits[key] <= 0
max_amount = item.quantity - item_limits[key]
item_limits[key] -= needs_limiting ? max_amount : item.quantity
else
needs_limiting = true if item.quantity > @Per _item_limit
max_amount = item.quantity - @Per _item_limit
end

if needs_limiting
if needs_deleted
to_delete << index
else
item.split(take: max_amount)
end
end
end

if to_delete.length > 0
del_index = -1
cart.line_items.delete_if do |item|
del_index += 1
true if to_delete.include?(del_index)
end
end

end
end
end

class Selector
def partial_match(match_type, item_info, possible_matches)
match_type = (match_type.to_s + ‘?’).to_sym
if item_info.kind_of?(Array)
possible_matches.any? do |possibility|
item_info.any? do |search|
search.send(match_type, possibility)
end
end
else
possible_matches.any? do |possibility|
item_info.send(match_type, possibility)
end
end
end
end

class ProductIdSelector < Selector
def initialize(match_type, product_ids)
@invert = match_type == :not_one
@Product_1 _ids = product_ids.map { |id| id.to_i }
end

def match?(line_item)
@invert ^ @Product_1 _ids.include?(line_item.variant.product.id)
end
end

CAMPAIGNS = [
QuantityLimit.new(
:all,
nil,
nil,
ProductIdSelector.new(
:is_one,
[“11851730639”]
),
:product,
1
)
].freeze

CAMPAIGNS.each do |campaign|
campaign.run_with_hooks(Input.cart)
end

Output.cart = Input.cart

Hello @Kumar2573

Check out these apps
https://apps.shopify.com/purchase-limit?

https://apps.shopify.com/limit-sales-per-day?

I saw your question about limiting purchases per customer. DC Order Limits can handle this without custom code by tracking what a customer has already purchased across orders and blocking checkout once they hit the limit.

If you are using Shopify Flow, you can also automate resets or build custom workflows around the same limit logic.