Class: Edi::MiraklSeller::PriceMessageProcessor

Inherits:
BaseEdiService show all
Defined in:
app/services/edi/mirakl_seller/price_message_processor.rb

Constant Summary

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

#append_catalog_items(xml, items) ⇒ Object



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
73
74
75
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
# File 'app/services/edi/mirakl_seller/price_message_processor.rb', line 46

def append_catalog_items(xml, items)
  items.each do |item|
   main_ci = item.catalog_items.find_by(catalog_id: orchestrator.main_catalog_id)
   if orchestrator.product_id_type == 'EAN'
    identifier = item.ean13
   elsif orchestrator.product_id_type == 'SHOP_SKU'
    identifier = item.sku
   end

    xml.send(:offer) do
      if orchestrator.offer_id == 'sku'
        create_attribute(xml, 'sku', item.sku)
      else
        create_attribute(xml, 'sku', item.ean13)
      end
      create_attribute(xml, 'product-id', identifier)
      create_attribute(xml, 'product-id-type', orchestrator.product_id_type)
      create_attribute(xml, 'price', main_ci&.price_with_vat)
      if main_ci.sale_price_with_vat.present?
        create_attribute(xml, 'discount-price', main_ci.sale_price_with_vat)
        create_attribute(xml, 'discount-start-date', (main_ci.sale_price_effective_date.to_datetime.strftime("%Y-%m-%dT%H:%M:%S+00") rescue nil))
        create_attribute(xml, 'discount-end-date', (main_ci.sale_price_expiration_date.to_datetime.strftime("%Y-%m-%dT%H:%M:%S+00") rescue nil))
      elsif main_ci.new_sale_price_with_vat.present?
        create_attribute(xml, 'discount-price', main_ci.new_sale_price_with_vat)
        create_attribute(xml, 'discount-start-date', (main_ci.new_sale_price_effective_date.to_datetime.strftime("%Y-%m-%dT%H:%M:%S+00") rescue nil))
        create_attribute(xml, 'discount-end-date', (main_ci.new_sale_price_expiration_date.to_datetime.strftime("%Y-%m-%dT%H:%M:%S+00") rescue nil))
      else
        create_attribute(xml, 'discount-price', nil)
        create_attribute(xml, 'discount-start-date', nil)
        create_attribute(xml, 'discount-end-date', nil)
      end
      create_attribute(xml, 'quantity', generate_product_inventory_data(item, orchestrator.main_catalog_id))
      create_attribute(xml, 'state', 11) #State New is 11
      create_attribute(xml, 'leadtime-to-ship', 4)
      create_attribute(xml, 'update-delete', 'update') #TODO: allow deleting offers
      xml.send(:'all-prices') do
        target_catalogs.each do |catalog|
          if (ci = item.catalog_items.find_by(catalog_id: catalog.id))
            xml.send(:pricing) do
              create_attribute(xml, 'channel-code', orchestrator.catalog_ids.key(catalog.id).to_s)
              create_attribute(xml, 'price', ci.price_with_vat)
              if ci.sale_price_with_vat.present?
                create_attribute(xml, 'discount-price', ci.sale_price_with_vat)
                create_attribute(xml, 'discount-start-date', (ci.sale_price_effective_date.to_datetime.strftime("%Y-%m-%dT%H:%M:%S+00") rescue nil))
                create_attribute(xml, 'discount-end-date', (ci.sale_price_expiration_date.to_datetime.strftime("%Y-%m-%dT%H:%M:%S+00") rescue nil))
              elsif ci.new_sale_price_with_vat.present?
                create_attribute(xml, 'discount-price', ci.new_sale_price_with_vat)
                create_attribute(xml, 'discount-start-date', (ci.new_sale_price_effective_date.to_datetime.strftime("%Y-%m-%dT%H:%M:%S+00") rescue nil))
                create_attribute(xml, 'discount-end-date', (ci.new_sale_price_expiration_date.to_datetime.strftime("%Y-%m-%dT%H:%M:%S+00") rescue nil))
              end
            end
          end
        end
      end
      xml.send(:'offer-additional-fields') do
        create_code_value_attribute(xml, 'vat-lmfr', 'Standard', 'offer-additional-field')
        create_code_value_attribute(xml, 'vat-bmfr', 'Standard', 'offer-additional-field')
        create_code_value_attribute(xml, 'vat-lmit', 'Standard', 'offer-additional-field')
        create_code_value_attribute(xml, 'vat-lmes', 'Standard', 'offer-additional-field')
        create_code_value_attribute(xml, 'vat-lmpt', 'Standard', 'offer-additional-field')
        create_code_value_attribute(xml, 'typologie-prix-de-depart', 'prix-de-reference', 'offer-additional-field')
        create_code_value_attribute(xml, 'tva', (main_ci.catalog.tax_rate * 100), 'offer-additional-field')
        create_code_value_attribute(xml, 'shipment-origin', 'NL', 'offer-additional-field')
      end
    end
  end
  xml
end

#build_xml(items: nil, catalog_items: nil, states: nil) ⇒ Object



34
35
36
37
38
39
40
41
42
43
44
# File 'app/services/edi/mirakl_seller/price_message_processor.rb', line 34

def build_xml(items: nil, catalog_items: nil, states: nil)
  logger.info "#{items.size} items in price payload"
  b = Nokogiri::XML::Builder.new(:encoding => 'UTF-8') do |xml|
    xml.import('xmlns:xsi': "http://www.w3.org/2001/XMLSchema-instance", 'xmlns:xsd': "http://www.w3.org/2001/XMLSchema") do
      xml.send(:offers) do
        append_catalog_items(xml, items)
      end
    end
  end
  b.to_xml
end

#create_attribute(xml, key, value) ⇒ Object



115
116
117
# File 'app/services/edi/mirakl_seller/price_message_processor.rb', line 115

def create_attribute(xml, key, value)
  xml.send(key.to_sym, value)
end

#create_code_value_attribute(xml, key, value, parent_group = nil) ⇒ Object



119
120
121
122
123
124
125
126
127
128
129
130
131
# File 'app/services/edi/mirakl_seller/price_message_processor.rb', line 119

def create_code_value_attribute(xml, key, value, parent_group=nil)
  if parent_group.present?
    xml.send(parent_group.to_sym) do
      xml.send(:code, key)
      xml.send(:value, value)
    end
  else
    xml.send(:attribute) do
      xml.send(:code, key)
      xml.send(:value, value)
    end
  end
end

#generate_product_inventory_data(item, catalog_id) ⇒ Object



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
# File 'app/services/edi/mirakl_seller/price_message_processor.rb', line 133

def generate_product_inventory_data(item, catalog_id )
  si = StoreItem.joins(catalog_items: :item).available.where(catalog_items: { catalog_id: catalog_id }).find_by(item_id: item.id)
  if si
    if si.unlimited_inventory?
      stock = si.permanent_qty_available
    else
      stock = si.qty_available
    end
  else
    msg = "Mirakl data feed - Unable to find suitable inventory for item #{item.sku} for catalog id #{catalog_id}, reporting 0 stock for now"
    ErrorReporting.warning(msg)
    Rails.logger.error msg
  end
  stock
end

#load_itemsObject



26
27
28
29
30
31
32
# File 'app/services/edi/mirakl_seller/price_message_processor.rb', line 26

def load_items
  catalog_items = CatalogItem.for_orchestrator_keys(orchestrator.config[:orchestrator_keys])
  items = Item.where.not(upc: [nil,'']).joins(:catalog_items).merge(catalog_items).distinct
  { items: items, catalog_items: catalog_items }

  #{ items: Item.where(id: 10689), catalog_items: CatalogItem.where(id:46152)} # For testing
end

#process(catalog_items: nil, states: nil) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'app/services/edi/mirakl_seller/price_message_processor.rb', line 5

def process(catalog_items: nil, states: nil)
  ecl = nil
  EdiCommunicationLog.transaction do
    logger.info "Creating price advice for partner #{orchestrator.partner}"
    load_result = load_items
    items = load_result[:items]
    catalog_items = load_result[:catalog_items]
    data_xml = build_xml(items: items, catalog_items: catalog_items, states: states)
    ecl = EdiCommunicationLog.create_outbound_file_from_data(
        data: data_xml,
        file_extension: 'xml',
        file_name: "wy-api-offer-export-#{Time.now.strftime('%Y%m%d%H%M%S')}.xml",
        partner: orchestrator.partner,
        category: 'price_advice',
        data_type: 'xml',
        file_info: {}
      )
  end
  ecl
end

#target_catalogsObject



149
150
151
# File 'app/services/edi/mirakl_seller/price_message_processor.rb', line 149

def target_catalogs
  Catalog.with_orchestrator_key.where(orchestrator_key: orchestrator.config[:orchestrator_keys])
end