Class: Edi::Wayfair::ListingGenerator::ListingGenerator

Inherits:
Object
  • Object
show all
Defined in:
app/services/edi/wayfair/listing_generator/listing_generator.rb

Overview

Generates Wayfair product update payloads using taxonomy-based attributes
Similar to Amazon's JsonListingGenerator but for Wayfair's updateMarketSpecificCatalogItems mutation

Usage:
generator = ListingGenerator.new(catalog_item)
payload = generator.generate

=> { supplierPartNumber: "SKU123", attributes: [...] }

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(catalog_item, wayfair_schema: nil) ⇒ ListingGenerator

Returns a new instance of ListingGenerator.



16
17
18
19
20
# File 'app/services/edi/wayfair/listing_generator/listing_generator.rb', line 16

def initialize(catalog_item, wayfair_schema: nil)
  @catalog_item = catalog_item
  @wayfair_schema = wayfair_schema || fetch_schema
  @errors = []
end

Instance Attribute Details

#catalog_itemObject (readonly)

Returns the value of attribute catalog_item.



14
15
16
# File 'app/services/edi/wayfair/listing_generator/listing_generator.rb', line 14

def catalog_item
  @catalog_item
end

#errorsObject (readonly)

Returns the value of attribute errors.



14
15
16
# File 'app/services/edi/wayfair/listing_generator/listing_generator.rb', line 14

def errors
  @errors
end

#wayfair_schemaObject (readonly)

Returns the value of attribute wayfair_schema.



14
15
16
# File 'app/services/edi/wayfair/listing_generator/listing_generator.rb', line 14

def wayfair_schema
  @wayfair_schema
end

Instance Method Details

#attribute_coverageHash

Check which attributes can be mapped

Returns:

  • (Hash)

    { mappable: [...], missing: [...], unmapped_required: [...] }



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
# File 'app/services/edi/wayfair/listing_generator/listing_generator.rb', line 58

def attribute_coverage
  return { mappable: [], missing: [], unmapped_required: [] } unless wayfair_schema

  available = Attributes::AttributeFactory.attributes_available
  wayfair_schema.attribute_ids
  required_ids = wayfair_schema.required_attributes.pluck('taxonomyAttributeId')

  mappable = []
  missing = []
  unmapped_required = []

  available.each do |attr_name|
    mapper = Attributes::AttributeFactory.build(attr_name, catalog_item: catalog_item, wayfair_schema: wayfair_schema)
    if mapper.build.present?
      mappable << attr_name
    else
      missing << attr_name
    end
  rescue StandardError => e
    Rails.logger.debug { "ListingGenerator: Error checking #{attr_name}: #{e.message}" }
    missing << attr_name
  end

  # Find required attributes we don't have mappers for
  Attributes::AttributeFactory.attributes_by_taxonomy_id.each do |id, _klass|
    next unless required_ids.include?(id) && mappable.none? do |m|
      Attributes::AttributeFactory.build(m, catalog_item: catalog_item, wayfair_schema: wayfair_schema).taxonomy_attribute_id == id
    rescue StandardError
      false
    end

    attr_def = wayfair_schema.find_attribute(id)
    unmapped_required << { id: id, title: attr_def&.dig('title') }
  end

  { mappable: mappable, missing: missing, unmapped_required: unmapped_required }
end

#generate(attributes: nil) ⇒ Hash

Generate the full update payload

Parameters:

  • attributes (Array<String>, nil) (defaults to: nil)

    Optional list of attribute names to include (nil = all available)

Returns:

  • (Hash)

    The update payload for updateMarketSpecificCatalogItems



25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'app/services/edi/wayfair/listing_generator/listing_generator.rb', line 25

def generate(attributes: nil)
  @errors = []

  unless wayfair_schema
    @errors << 'No Wayfair schema available for this catalog item'
    return nil
  end

  attribute_payloads = build_attribute_payloads(attributes)

  if attribute_payloads.empty?
    @errors << 'No attributes could be mapped'
    return nil
  end

  {
    supplierPartNumber: supplier_part_number,
    attributes: attribute_payloads
  }
end

#generate_required_onlyObject

Generate payload for only required attributes



47
48
49
50
51
52
53
54
# File 'app/services/edi/wayfair/listing_generator/listing_generator.rb', line 47

def generate_required_only
  required_ids = wayfair_schema&.required_attributes&.pluck('taxonomyAttributeId') || []
  required_names = required_ids.filter_map do |id|
    Attributes::AttributeFactory.attributes_by_taxonomy_id[id]&.attribute_name
  end

  generate(attributes: required_names)
end

#previewObject

Preview what would be sent (for debugging)



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'app/services/edi/wayfair/listing_generator/listing_generator.rb', line 97

def preview
  payload = generate
  return { error: errors.first } unless payload

  {
    supplier_part_number: payload[:supplierPartNumber],
    attribute_count: payload[:attributes].size,
    attributes: payload[:attributes].map do |attr|
      {
        id: attr[:taxonomyAttributeId],
        title: wayfair_schema.find_attribute(attr[:taxonomyAttributeId])&.dig('title'),
        value: attr[:value] || attr[:values]
      }
    end
  }
end