How can I limit product purchase quantity per customer?

How can I limit product purchase quantity per customer?

Kumar2573
Shopify Partner
174 8 23

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_ids = product_ids.map { |id| id.to_i }
end

def match?(line_item)
@invert ^ @Product_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

Shopify Certified Developer Profile - https://www.credly.com/badges/1733d05c-2a88-490a-aef5-b01baf3b94ce/public_url
Expert Shopify Plus & shopify Developer & Theme customizer
- If the problem is solved remember to click to Accept Solution
- Press Like ?? if the answer was helpful
- Still, Facing issue, Reach out to me Email :- jitendra3496@gmail.com | Skype :- jitendra2573_1
- Direct Hire me :- Direct Contact me
Reply 1 (1)

magecomp
Shopify Partner
450 31 47

Hello @Kumar2573 

 

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

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

Helping voluntarily. Please like and accept the solution if it helps. Thanks!
Our Bestseller Shopify Apps    |      Mobile App Builder by MageComp    |      Shoplock Hide Pages/Collections

Need a developer?  Just visit MageComp website