Module: ProdMktQueryConcern

Extended by:
AcumenQueryConcern
Included in:
Agents::AcumenProductAgent
Defined in:
lib/huginn_acumen_product_agent/concerns/prod_mkt_query_concern.rb,
lib/huginn_acumen_product_agent/concerns/inv_status_query_concern.rb

Overview

This module is responsible for reading/processing the Inv_Status table. This table contains stock information for the product and is tied to product availability.

Constant Summary

Constants included from AcumenQueryConcern

AcumenQueryConcern::UNIT_MAP

Instance Method Summary collapse

Instance Method Details

#fetch_inv_status(acumen_client, products) ⇒ Object

Update the provided products with their associated marketing data NOTE: The ‘products` here are Shema.org/Product records mapped from Inv_Product data



11
12
13
14
15
16
17
18
# File 'lib/huginn_acumen_product_agent/concerns/inv_status_query_concern.rb', line 11

def fetch_inv_status(acumen_client, products)

  product_skus = products.map { |p| p['sku'] }
  inventory_data = acumen_client.get_inv_status(product_skus)
  inventory_data = process_inv_status_response(inventory_data)

  return map_inv_status_data(products, inventory_data)
end

#fetch_product_marketing(acumen_client, products) ⇒ Object

Update the provided products with their associated marketing data NOTE: The ‘products` here are Shema.org/Product records mapped from Inv_Product data



12
13
14
15
16
17
18
19
# File 'lib/huginn_acumen_product_agent/concerns/prod_mkt_query_concern.rb', line 12

def fetch_product_marketing(acumen_client, products)

  product_ids = products.map { |p| p['identifier'] }
  marketing_data = acumen_client.get_products_marketing(product_ids)
  marketing_data = process_prod_mkt_response(marketing_data)

  return map_marketing_data(products, marketing_data)
end

#map_inv_status_data(products, inventory) ⇒ Object

This function maps parsed Prod_Mkt records to their matching product record and updates the product object with the additional data



50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
# File 'lib/huginn_acumen_product_agent/concerns/inv_status_query_concern.rb', line 50

def map_inv_status_data(products, inventory)
  products.map do |product|
    inventory_data = inventory.select { |i| i['sku'] == product['sku'] }
    begin

      if inventory_data
        quantity = 0
        inventory_data.each do |i|
          quantity = quantity + i['quantity'].to_i if quantity.present?
        end

        product['acumenAttributes']['stock_quantity'] = quantity
      end

    rescue => error
      issue_error(AcumenAgentError.new(
        'map_inv_status_data',
        'Failed to map inventory data for product',
        { sku: product['sku'] },
        error,
      ))
    end

    product
  end

  return products
end

#map_marketing_data(products, marketing_data) ⇒ Object

This function maps parsed Prod_Mkt records to their matching product record and updates the product object with the additional data



76
77
78
79
80
81
82
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
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
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
# File 'lib/huginn_acumen_product_agent/concerns/prod_mkt_query_concern.rb', line 76

def map_marketing_data(products, marketing_data)
  products.map do |product|
    marketing = marketing_data[product['identifier']]

    begin

      if marketing
        product['acumenAttributes']['product_marketing_id'] = marketing['id']

        product['publisher'] = {
          '@type': 'Organization',
          'name' => marketing['publisher']
        };
        product['description'] = marketing['description_long']
        product['abstract'] = marketing['description_short']
        product['keywords'] = marketing['meta_keywords']
        product['text'] = marketing['excerpt']

        if marketing['age_lowest'] && marketing['age_highest']
          product['typicalAgeRange'] = "#{marketing['age_lowest']}-#{marketing['age_highest']}"
        end

        #----------  Product Page Attributes  ----------#
        if marketing['grade_lowest'] || marketing['grade_highest']
          # educationalUse? educationalAlignment?
          product['additionalProperty'].push({
            '@type' => 'PropertyValue',
            'name' => 'Grade',
            'propertyID' => 'grade_range',
            'minValue' => marketing['grade_lowest'],
            'maxValue' => marketing['grade_highest'],
            'value' => "#{marketing['grade_lowest']}-#{marketing['grade_highest']}",
          })
        end

        if marketing['awards']
          product['additionalProperty'].push({
            '@type' => 'PropertyValue',
            'propertyID' => 'awards',
            'name' => 'Awards',
            'value' => marketing['awards'],
          })
        end

        #----------  Acumen Specific Properties  ----------#
        product['acumenAttributes']['extent_unit'] = marketing['extent_unit']
        product['acumenAttributes']['extent_value'] = marketing['extent_value']
        product['acumenAttributes']['info_text_01'] = marketing['info_text_01'] # editorial_reviews
        product['acumenAttributes']['info_text_02'] = marketing['info_text_02'] # product_samples
        product['acumenAttributes']['info_alpha_07'] = marketing['info_alpha_07'] # video_urls
        product['acumenAttributes']['meta_description'] = marketing['meta_description']
        product['acumenAttributes']['religious_text_identifier'] = marketing['religious_text_identifier']
        product['acumenAttributes']['status'] = marketing['status']

        product['gtin12'] = marketing['upc']
        product['numberOfPages'] = marketing['pages']

        product['height'] = get_quantitative_value(
          marketing['height'], marketing['dimensions_unit_measure']
        )
        product['width'] = get_quantitative_value(
          marketing['width'], marketing['dimensions_unit_measure']
        )
        product['depth'] = get_quantitative_value(
          marketing['thickness'], marketing['dimensions_unit_measure']
        )
        if product['weight']['value'] == '0'
            product['weight'] = get_quantitative_value(
              marketing['weight'], marketing['weight_unit_measure']
            )
        end
      end

    rescue => error
      issue_error(AcumenAgentError.new(
        'map_marketing_data',
        'Failed to map marketing data for product',
        { id: product['identifier'], sku: marketing['sku'] },
        error,
      ))
    end

    product
  end

  return products
end

#process_inv_status_response(raw_data) ⇒ Object

This function parses the raw data returned from the Prod_Mkt table



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/huginn_acumen_product_agent/concerns/inv_status_query_concern.rb', line 21

def process_inv_status_response(raw_data)
  results = []
  raw_data.map do |inv_status|

    begin
      mapped = response_mapper(inv_status, {
        'Inv_Status.Warehouse' => 'warehouse',
        'Inv_Status.ProdCode' => 'sku',
        'Inv_Status.Available' => 'quantity',
      })

      if (mapped['warehouse'] === 'Main Warehouse')
        results << mapped
      end
    rescue => error
      issue_error(AcumenAgentError.new(
        'process_inv_status_response',
        'Failed while processing Prod_Mkt record',
        { sku: get_field_value(inv_status, 'Inv_Status.ProdCode') },
        error,
      ))
    end
  end

  results
end

#process_prod_mkt_response(raw_data) ⇒ Object

This function parses the raw data returned from the Prod_Mkt table



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/huginn_acumen_product_agent/concerns/prod_mkt_query_concern.rb', line 22

def process_prod_mkt_response(raw_data)
  results = {}
  raw_data.map do |product_marketing|

    begin
      mapped = response_mapper(product_marketing, {
        'ProdMkt.Product_ID' => 'product_id',
        'ProdMkt.Product_Code' => 'sku',
        'ProdMkt.ID' => 'id',
        'ProdMkt.Pages' => 'pages',
        'ProdMkt.Publisher' => 'publisher',
        'ProdMkt.Description_Short' => 'description_short',
        'ProdMkt.Description_Long' => 'description_long',
        'ProdMkt.Height' => 'height',
        'ProdMkt.Width' => 'width',
        'ProdMkt.Thickness' => 'thickness',
        'ProdMkt.Meta_Keywords' => 'meta_keywords',
        'ProdMkt.Meta_Description' => 'meta_description',
        'ProdMkt.Extent_Unit' => 'extent_unit',
        'ProdMkt.Extent_Value' => 'extent_value',
        'ProdMkt.Age_Highest' => 'age_highest',
        'ProdMkt.Age_Lowest' => 'age_lowest',
        'ProdMkt.Awards' => 'awards',
        'ProdMkt.Dimensions_Unit_Measure' => 'dimensions_unit_measure',
        'ProdMkt.Excerpt' => 'excerpt',
        'ProdMkt.Grade_Highest' => 'grade_highest',
        'ProdMkt.Grade_Lowest' => 'grade_lowest',
        'ProdMkt.Status' => 'status',
        'ProdMkt.UPC' => 'upc',
        'ProdMkt.Weight_Unit_Measure' => 'weight_unit_measure',
        'ProdMkt.Weight' => 'weight',
        'ProdMkt.Info_Text_01' => 'info_text_01',
        'ProdMkt.Info_Text_02' => 'info_text_02',
        'ProdMkt.Religious_Text_Identifier' => 'religious_text_identifier',
        'ProdMkt.Info_Alpha_07' => 'info_alpha_07',
      })

      results[mapped['product_id']] = mapped
      # NOTE: In this case, product_id matches the Inv_Product.ID fields
    rescue => error
      issue_error(AcumenAgentError.new(
        'process_prod_mkt_response',
        'Failed while processing Prod_Mkt record',
        { sku: get_field_value(product_marketing, 'ProdMkt.Product_Code') },
        error,
      ))
    end
  end

  results
end