######################################################################## ## Create Shopify scripts without writing code at playwrightapp.com ## ######################################################################## class Campaign def initialize(condition, *qualifiers) @condition = (condition.to_s + '?').to_sym @qualifiers = PostCartAmountQualifier ? [] : [] rescue qualifiers.compact @line_item_selector = qualifiers.last unless @line_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, @line_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 ConditionallyHideRates < Campaign def initialize(condition, customer_qualifier, cart_qualifier, li_match_type, line_item_qualifier, rate_selector) super(condition, customer_qualifier, cart_qualifier, line_item_qualifier) @li_match_type = (li_match_type.to_s + '?').to_sym @rate_selector = rate_selector end def run(rates, cart) rates.delete_if { |rate| @rate_selector.match?(rate) } if qualifies?(cart) end end class FullAddressQualifier def initialize(addresses) @addresses = addresses end def match?(cart, selector = nil) return false if cart.shipping_address.nil? @addresses.any? do |accepted_address| match_type = accepted_address[:match_type].to_sym cart.shipping_address.to_hash.all? do |key, value| key = key.to_sym next true unless accepted_address[key] next true if accepted_address[key].length === 0 next false if value.nil? value.downcase! match = accepted_address[key].any? do |potential_address| potential_address.downcase! case match_type when :partial value.include?(potential_address) when :exact potential_address == value end end match 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 RateNameSelector < Selector def initialize(match_type, match_condition, names) @match_condition = match_condition @invert = match_type == :does_not @names = names.map(&:downcase) end def match?(shipping_rate) name = shipping_rate.name.downcase case @match_condition when :match return @invert ^ @names.include?(name) else return @invert ^ partial_match(@match_condition, name, @names) end end end CAMPAIGNS = [ ConditionallyHideRates.new( :all, nil, FullAddressQualifier.new( [ {:address1 => ["andrés bello 2425"], :address2 => ["local 1126"], :phone => [], :city => ["Providencia"], :province_code => ["RM"], :country_code => ["CL"], :zip => [], :match_type => "partial"}, {:address1 => ["kennedy lateral 9001"], :address2 => ["local 2175"], :phone => [], :city => ["las condes"], :province_code => ["RM"], :country_code => ["CL"], :zip => [], :match_type => "partial"}, {:address1 => ["kennedy 5413"], :address2 => ["local 306"], :phone => [], :city => ["las condes"], :province_code => ["RM"], :country_code => ["CL"], :zip => [], :match_type => "partial"}] ), :any, nil, RateNameSelector.new( :does, :include, ["adespacho"] ) ) ].freeze CAMPAIGNS.each do |campaign| campaign.run(Input.shipping_rates, Input.cart) end Output.shipping_rates = Input.shipping_rates