class ZuoraConnect::AppInstanceBase

def get_catalog(page_size: 5, zuora_login: self.login_lookup(type: "Zuora").first, entity_id: nil)

## START Catalog Helping Methods #####
def get_catalog(page_size: 5, zuora_login: self.login_lookup(type: "Zuora").first, entity_id: nil)
  self.update_column(:catalog_update_attempt_at, Time.now.utc)
  entity_reference = entity_id.blank? ? 'Default' : entity_id
  Rails.logger.debug("Fetch Catalog")
  Rails.logger.debug("Zuora Entity: #{entity_id.blank? ? 'default' : entity_id}")
  login = zuora_login.client(entity_reference)
  old_logger = ActiveRecord::Base.logger
  ActiveRecord::Base.logger = nil
  ActiveRecord::Base.connection.execute('UPDATE "public"."zuora_connect_app_instances" SET "catalog" = jsonb_set("catalog", \'{tmp}\', \'{}\'), "catalog_mapping" = jsonb_set("catalog_mapping", \'{tmp}\', \'{}\') where "id" = %{id}' % {:id => self.id})
  response = {'nextPage' => login.rest_endpoint("catalog/products?pageSize=#{page_size}")}
  while !response["nextPage"].blank?
    url = login.rest_endpoint(response["nextPage"].split('/v1/').last)
    Rails.logger.debug("Fetch Catalog URL #{url}")
    output_json, response = login.rest_call(:debug => false, :url => url, :errors => [ZuoraAPI::Exceptions::ZuoraAPISessionError], :timeout_retry => true)
    Rails.logger.debug("Fetch Catalog Response Code #{response.code}")
    if !output_json['success'] =~ (/(true|t|yes|y|1)$/i) || output_json['success'].class != TrueClass
      Rails.logger.error("Fetch Catalog DATA #{output_json.to_json}")
      raise ZuoraAPI::Exceptions::ZuoraAPIError.new("Error Getting Catalog: #{output_json}")
    end
    output_json["products"].each do |product|
      ActiveRecord::Base.connection.execute('UPDATE "public"."zuora_connect_app_instances" SET "catalog_mapping" = jsonb_set("catalog_mapping", \'{tmp, %s}\', \'%s\') where "id" = %s' % [product["id"], {"productId" => product["id"]}.to_json.gsub("'", "''"), self.id])
      rateplans = {}
      product["productRatePlans"].each do |rateplan|
        ActiveRecord::Base.connection.execute('UPDATE "public"."zuora_connect_app_instances" SET "catalog_mapping" = jsonb_set("catalog_mapping", \'{tmp, %s}\', \'%s\') where "id" = %s' % [rateplan["id"],  {"productId" => product["id"], "productRatePlanId" => rateplan["id"]}.to_json.gsub("'", "''"), self.id])
        charges = {}
        rateplan["productRatePlanCharges"].each do |charge|
          ActiveRecord::Base.connection.execute('UPDATE "public"."zuora_connect_app_instances" SET "catalog_mapping" = jsonb_set("catalog_mapping", \'{tmp, %s}\', \'%s\') where "id" = %s' % [charge["id"],  {"productId" => product["id"], "productRatePlanId" => rateplan["id"], "productRatePlanChargeId" => charge["id"]}.to_json.gsub("'", "''"), self.id])
          charges[charge["id"]] = charge.merge({"productId" => product["id"], "productName" => product["name"], "productRatePlanId" => rateplan["id"], "productRatePlanName" => rateplan["name"] })
        end
        rateplan["productRatePlanCharges"] = charges
        rateplans[rateplan["id"]] = rateplan.merge({"productId" => product["id"], "productName" => product["name"]})
      end
      product["productRatePlans"] = rateplans
      ActiveRecord::Base.connection.execute('UPDATE "public"."zuora_connect_app_instances" SET "catalog" = jsonb_set("catalog", \'{tmp, %s}\', \'%s\') where "id" = %s' % [product["id"], product.to_json.gsub("'", "''"), self.id])
    end
  end
  # Move from tmp to actual
  ActiveRecord::Base.connection.execute('UPDATE "public"."zuora_connect_app_instances" SET "catalog" = jsonb_set("catalog", \'{%{entity}}\', "catalog" #> \'{tmp}\'), "catalog_mapping" = jsonb_set("catalog_mapping", \'{%{entity}}\',  "catalog_mapping" #> \'{tmp}\') where "id" = %{id}' % {:entity => entity_reference, :id => self.id})
  if defined?(Redis.current)
    Redis.current.keys("Catalog:#{self.id}:*").each do |key|
      Redis.current.del(key.to_s)
    end
  end
  # Clear tmp holder
  ActiveRecord::Base.connection.execute('UPDATE "public"."zuora_connect_app_instances" SET "catalog" = jsonb_set("catalog", \'{tmp}\', \'{}\'), "catalog_mapping" = jsonb_set("catalog_mapping", \'{tmp}\', \'{}\') where "id" = %{id}' % {:id => self.id})
  ActiveRecord::Base.logger = old_logger
  self.update_column(:catalog_updated_at, Time.now.utc)
  self.touch
  # DO NOT RETURN CATALOG. THIS IS NOT SCALABLE WITH LARGE CATALOGS. USE THE  CATALOG_LOOKUP method provided
  return true
end