Class: Edi::Wayfair::ListingGenerator::ListingGenerator
- Inherits:
-
Object
- Object
- Edi::Wayfair::ListingGenerator::ListingGenerator
- 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
-
#catalog_item ⇒ CatalogItem
readonly
The catalog item being mapped.
-
#errors ⇒ Object
readonly
Returns the value of attribute errors.
-
#wayfair_schema ⇒ WayfairSchema?
readonly
The resolved taxonomy schema for the item's class.
Instance Method Summary collapse
-
#attribute_coverage ⇒ Hash
Check which attributes can be mapped for this item's class.
-
#generate(attributes: nil) ⇒ Hash
Generate the full update payload.
-
#generate_required_only ⇒ Hash?
Generate payload for only the attributes the class marks REQUIRED that we can map.
-
#initialize(catalog_item, wayfair_schema: nil) ⇒ ListingGenerator
constructor
A new instance of ListingGenerator.
-
#preview ⇒ Hash
Preview what would be sent (for debugging).
Constructor Details
#initialize(catalog_item, wayfair_schema: nil) ⇒ ListingGenerator
Returns a new instance of ListingGenerator.
31 32 33 34 35 |
# File 'app/services/edi/wayfair/listing_generator/listing_generator.rb', line 31 def initialize(catalog_item, wayfair_schema: nil) @catalog_item = catalog_item @wayfair_schema = wayfair_schema || fetch_schema @errors = [] end |
Instance Attribute Details
#catalog_item ⇒ CatalogItem (readonly)
Returns the catalog item being mapped.
26 27 28 |
# File 'app/services/edi/wayfair/listing_generator/listing_generator.rb', line 26 def catalog_item @catalog_item end |
#errors ⇒ Object (readonly)
Returns the value of attribute errors.
26 |
# File 'app/services/edi/wayfair/listing_generator/listing_generator.rb', line 26 attr_reader :catalog_item, :wayfair_schema, :errors |
#wayfair_schema ⇒ WayfairSchema? (readonly)
Returns the resolved taxonomy schema for the item's class.
26 |
# File 'app/services/edi/wayfair/listing_generator/listing_generator.rb', line 26 attr_reader :catalog_item, :wayfair_schema, :errors |
Instance Method Details
#attribute_coverage ⇒ Hash
Check which attributes can be mapped for this item's class.
83 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 |
# File 'app/services/edi/wayfair/listing_generator/listing_generator.rb', line 83 def attribute_coverage return { mappable: [], missing: [], unmapped_required: [] } unless wayfair_schema mappable = [] missing = [] mapped_ids = [] Attributes::AttributeFactory.attributes_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 mapped_ids << mapper.taxonomy_attribute_id.to_s else missing << attr_name end rescue StandardError => e Rails.logger.debug { "ListingGenerator: Error checking #{attr_name}: #{e.}" } missing << attr_name end unmapped_required = wayfair_schema.required_attributes.filter_map do |attr| id = attr['taxonomyAttributeId'].to_s # Only class-specific product specs, identified by a bare numeric id (any # datatype — Material/Thermostat Type are MULTI_CHOICE/SINGLE_CHOICE). The # namespaced core::/price::/shippingAndFulfillment::/propSixtyFive:: platform # fields and the structural Class ID (1) are supplied by other systems, not # these attribute mappers. next unless id.match?(/\A\d+\z/) && id != '1' next if mapped_ids.include?(id) { id: id, title: attr['title'] } end { mappable: mappable, missing: missing, unmapped_required: unmapped_required } end |
#generate(attributes: nil) ⇒ Hash
Generate the full update payload
40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'app/services/edi/wayfair/listing_generator/listing_generator.rb', line 40 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_only ⇒ Hash?
Generate payload for only the attributes the class marks REQUIRED that we
can map. Resolves each mapper against the live schema (by title) — the same
schema-driven resolution #attribute_coverage uses — so class-specific
required ids (e.g. floor-heating Wattage 383497) select the right mapper
instead of being missed by the legacy hardcoded-id registry.
68 69 70 71 72 73 |
# File 'app/services/edi/wayfair/listing_generator/listing_generator.rb', line 68 def generate_required_only required_ids = wayfair_schema&.required_attributes&.pluck('taxonomyAttributeId')&.map(&:to_s) || [] required_names = required_ids.empty? ? [] : mappers_for_required(required_ids) generate(attributes: required_names) end |
#preview ⇒ Hash
Preview what would be sent (for debugging)
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
# File 'app/services/edi/wayfair/listing_generator/listing_generator.rb', line 123 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 |