Class: Edi::Wayfair::TaxonomyAttributeRetriever

Inherits:
BaseEdiService show all
Defined in:
app/services/edi/wayfair/taxonomy_attribute_retriever.rb

Overview

Retrieves taxonomy attributes from Wayfair's Product Catalog API
Uses the attributesByFilter GraphQL query to get attribute definitions
for a specific taxonomy category.

These attributes define what product data can be updated via
the updateMarketSpecificCatalogItems mutation.

API Documentation: https://developer.wayfair.io/posts/docs/product-catalog-update-api/reference/GraphQL/v1.0.0

Constant Summary collapse

CATALOG_API_URL =

Product Catalog API endpoint (different from Supplier Catalog API)

'https://api.wayfair.io/v1/product-catalog-api/graphql'
SANDBOX_CATALOG_API_URL =
'https://api.wayfair.io/sandbox/v1/product-catalog-api/graphql'
ATTRIBUTES_BY_FILTER_QUERY =

GraphQL query to retrieve taxonomy attributes for a category

<<~GRAPHQL.squish
  query GetTaxonomyAttributesByFilter($input: AttributesFilterInput!) {
    attributesByFilter(input: $input) {
      taxonomyCategoryId
      attributes {
        taxonomyAttributeId
        title
        description
        requirement
        valueFormat {
          canValueBeCustomized
          canValueBeSetToUnavailable
          canValueBeSetToNotApplicable
          datatype
        }
        possibleAttributeValues {
          value
          definition
        }
        parentAttributeId
        childAttributes {
          taxonomyAttributeId
          title
          description
          valueFormat {
            canValueBeCustomized
            canValueBeSetToUnavailable
            canValueBeSetToNotApplicable
            datatype
          }
          parentAttributeId
          possibleAttributeValues {
            value
            definition
          }
        }
        relatedAttributeIds
        taxonomyCategoryIds
      }
      conditionalityRules {
        taxonomyAttributeId
        rules {
          upstreamCondition {
            taxonomyAttributeId
            answers
            operation
          }
          downstreamConditions {
            taxonomyAttributeId
            validationType
            answers
            operation
          }
        }
      }
    }
  }
GRAPHQL

Constants included from AddressAbbreviator

AddressAbbreviator::MAX_LENGTH

Instance Attribute Summary

Attributes inherited from BaseEdiService

#orchestrator

Instance Method Summary collapse

Methods inherited from BaseEdiService

#duplicate_po_already_notified?, #initialize, #mark_duplicate_po_as_notified, #report_order_creation_issues, #safe_process_edi_communication_log

Methods included from AddressAbbreviator

#abbreviate_street, #collect_street_originals, #record_address_abbreviation_notes

Methods inherited from BaseService

#initialize, #log_debug, #log_error, #log_info, #log_warning, #logger, #options, #tagged_logger

Constructor Details

This class inherits a constructor from Edi::BaseEdiService

Instance Method Details

#process(taxonomy_category_id:, brand: 'WAYFAIR', country: 'UNITED_STATES', locale: 'en-US', wayfair_schema: nil) ⇒ WayfairSchema?

Fetch taxonomy attributes for a category

Parameters:

  • taxonomy_category_id (Integer)

    The Wayfair taxonomy category ID (e.g., 997)

  • brand (String) (defaults to: 'WAYFAIR')

    Brand context (WAYFAIR, ALLMODERN, etc.)

  • country (String) (defaults to: 'UNITED_STATES')

    Country context (UNITED_STATES, CANADA, etc.)

  • locale (String) (defaults to: 'en-US')

    Locale (en-US, en-CA, etc.)

  • wayfair_schema (WayfairSchema) (defaults to: nil)

    Optional existing schema to update

Returns:

  • (WayfairSchema, nil)

    The created/updated schema or nil on failure



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'app/services/edi/wayfair/taxonomy_attribute_retriever.rb', line 84

def process(taxonomy_category_id:, brand: 'WAYFAIR', country: 'UNITED_STATES', locale: 'en-US', wayfair_schema: nil)
  variables = {
    input: {
      taxonomyCategoryId: taxonomy_category_id.to_i,
      marketContext: {
        brand: brand.to_s.upcase,
        country: country.to_s.upcase,
        locale: locale
      }
    }
  }

  logger.info "Wayfair Taxonomy: Fetching attributes for category #{taxonomy_category_id} (#{brand}/#{country}/#{locale})"
  logger.debug "Wayfair Taxonomy: Request URL: #{catalog_api_url}"

  transport = build_catalog_transport
  query_payload = build_graphql_payload(ATTRIBUTES_BY_FILTER_QUERY, variables)

  result = transport.send_request('POST', catalog_api_url, query_payload, transport.build_request_headers)
  http_response = result[:http_res]

  unless http_response&.status&.success?
    logger.error "Wayfair Taxonomy: Request failed with status #{http_response&.status}"
    return nil
  end

  response_body = http_response.body.to_s
  json_data = JSON.parse(response_body).with_indifferent_access

  if json_data[:errors].present?
    logger.error "Wayfair Taxonomy: GraphQL errors: #{json_data[:errors]}"
    return nil
  end

  schema_data = json_data.dig(:data, :attributesByFilter)
  if schema_data.blank?
    logger.warn "Wayfair Taxonomy: No attributes returned for category #{taxonomy_category_id}"
    return nil
  end

  # Create or update the WayfairSchema record
  wayfair_schema ||= WayfairSchema.find_or_initialize_by(
    taxonomy_category_id: taxonomy_category_id,
    brand: brand.to_s.upcase,
    country: country.to_s.upcase,
    locale: locale
  )

  wayfair_schema.schema = schema_data
  wayfair_schema.category_name = extract_category_name(schema_data)

  if wayfair_schema.save
    attributes_count = extract_attributes_list(schema_data).size
    logger.info "Wayfair Taxonomy: Saved schema for category #{taxonomy_category_id} with #{attributes_count} attributes"
    wayfair_schema
  else
    logger.error "Wayfair Taxonomy: Failed to save schema: #{wayfair_schema.errors.full_messages.join(', ')}"
    nil
  end
end