app/controllers/spree/api/retailops/catalog_controller.rb
# This is where most of the fun happens: for a product, apply changes
# and create if needed
This is where most of the fun happens: for a product, apply changes
and create if needed
This is where most of the fun happens : for a product apply changes and create if needed
def upsert_product_only(pd, variant_sets)
            variant_list = pd['variants'].to_a
            if !pd["varies"]
              return add_error("no variants specified") if variant_list.empty?
              v = variant_list[0]
              variant_list = []
              %w( images stock stock_detailed tax_category weight height depth width cost_price price cost_currency sku var_extend ).each do |c|
                pd[c] = v[c] if v.has_key?(c)
              end
            end
            return add_error("sku not specified") if pd["sku"].empty?
            ex_variant = Variant.includes(:product).where(sku: pd["sku"], deleted_at: nil).lock.first
            product = nil
            if ex_variant && !ex_variant.is_master
              product = Product.new { |p| p.master = ex_variant }
            elsif ex_variant
              product = ex_variant.product || Product.new
            else
              product = Product.new
            end
            update_if(pd, "tax_category") { |cat| product.tax_category = memo(:upsert_tax_category, cat) }
            update_if(pd, "available_on") { |avtime| product.available_on = avtime ? Time.at(avtime) : nil }
            update_if(pd, "slug") { |slug| product.slug = slug } if product.respond_to? :slug= 
            update_if(pd, "slug") { |slug| product.permalink = slug } if product.respond_to? :permalink= 
            update_if(pd, "name") { |name| product.name = name }
            update_if(pd, "meta_desc") { |md| product.meta_description = md }
            update_if(pd, "description") { |d| product.description = d }
            update_if(pd, "meta_keywords") { |mk| product.meta_keywords = mk }
            update_if(pd, "ship_category") { |sc| product.shipping_category = memo(:upsert_ship_category, sc) }
            update_if pd, "options_used" do |opts|
              product.option_types = pd["options_used"].to_a.map { |opt| memo(:upsert_option_type, opt) }
            end
            update_if pd, "taxa" do |taxa|
              product.taxons = taxa.to_a.map { |path| upsert_taxon_path(path) }
            end
            update_if pd, "properties" do |prop|
              ex_props = product.product_properties.to_a
              sequence = 1
              prop.to_a.each do |kv|
                prop = memo(:upsert_property, kv["key"]) or next
                kv["value"].present? or next
                pprop = ex_props.any?{|p| p.property == prop} ? ex_props.delete_at(ex_props.index{|p| p.property == prop}) : product.product_properties.build( property: prop )
                if pprop.value != kv["value"] || pprop.position != sequence
                  pprop.value = kv["value"]
                  pprop.position = sequence
                  pprop.save!
                end
                sequence += 1
              end
              ex_props.each(&:destroy!) if options['delete_old_properties']
            end
            update_if(pd, "prod_extend") { |e| apply_extensions product, e }
            upsert_variant(product, product.master, pd)
            product.save or return validate_to_error(product)
            unless tx_failed?
              variant_list.each { |v| variant_sets << lambda { with_correlation(v) { upsert_variant(product, nil, v) } } }
            end
          end
def upsert_product_only ( pd , variant_sets ) variant_list = pd [ 'variants' ] . to_a if ! pd [ "varies" ] return add_error ( "no variants specified" ) if variant_list . empty? v = variant_list [ 0 ] variant_list = [ ] %w( images stock stock_detailed tax_category weight height depth width cost_price price cost_currency sku var_extend ) . each do | c | pd [ c ] = v [ c ] if v . has_key? ( c ) end end return add_error ( "sku not specified" ) if pd [ "sku" ] . empty? ex_variant = Variant . includes ( :product ) . where ( sku : pd [ "sku" ] , deleted_at : nil ) . lock . first product = nil if ex_variant && ! ex_variant . is_master product = Product . new { | p | p . master = ex_variant } elsif ex_variant product = ex_variant . product || Product . new else product = Product . new end update_if ( pd , "tax_category" ) { | cat | product . tax_category = memo ( :upsert_tax_category , cat ) } update_if ( pd , "available_on" ) { | avtime | product . available_on = avtime ? Time . at ( avtime ) : nil } update_if ( pd , "slug" ) { | slug | product . slug = slug } if product . respond_to? :slug= update_if ( pd , "slug" ) { | slug | product . permalink = slug } if product . respond_to? :permalink= update_if ( pd , "name" ) { | name | product . name = name } update_if ( pd , "meta_desc" ) { | md | product . meta_description = md } update_if ( pd , "description" ) { | d | product . description = d } update_if ( pd , "meta_keywords" ) { | mk | product . meta_keywords = mk } update_if ( pd , "ship_category" ) { | sc | product . shipping_category = memo ( :upsert_ship_category , sc ) } update_if pd , "options_used" do | opts | product . option_types = pd [ "options_used" ] . to_a . map { | opt | memo ( :upsert_option_type , opt ) } end update_if pd , "taxa" do | taxa | product . taxons = taxa . to_a . map { | path | upsert_taxon_path ( path ) } end update_if pd , "properties" do | prop | ex_props = product . product_properties . to_a sequence = 1 prop . to_a . each do | kv | prop = memo ( :upsert_property , kv [ "key" ] ) or next kv [ "value" ] . present? or next pprop = ex_props . any? { | p | p . property == prop } ? ex_props . delete_at ( ex_props . index { | p | p . property == prop } ) : product . product_properties . build ( property : prop ) if pprop . value != kv [ "value" ] || pprop . position != sequence pprop . value = kv [ "value" ] pprop . position = sequence pprop . save! end sequence += 1 end ex_props . each ( & :destroy! ) if options [ 'delete_old_properties' ] end update_if ( pd , "prod_extend" ) { | e | apply_extensions product , e } upsert_variant ( product , product . master , pd ) product . save or return validate_to_error ( product ) unless tx_failed? variant_list . each { | v | variant_sets << lambda { with_correlation ( v ) { upsert_variant ( product , nil , v ) } } } end end
This is where most of the fun happens: for a product, apply changes
and create if needed
This is where most of the fun happens : for a product apply changes and create if needed
# in the non-varying case, copy data up # Try to use the existing SKU to pull up a product # HERE promoting this variant to be the master of a new product.  the new product is created, and this variant is moved into it and set to master # no product?  OK then # Update product attributes # renamed 2.2.x # renamed 2.2.x # set things that hang off the product # Create/update variants, including the master # product itself A-OK?  if not fail
pd
<not_specific>
variant_sets
<not_specific>