Class: Edi::Commercehub::ConfirmMessageProcessor
- Inherits:
-
BaseEdiService
- Object
- BaseService
- BaseEdiService
- Edi::Commercehub::ConfirmMessageProcessor
- Defined in:
- app/services/edi/commercehub/confirm_message_processor.rb
Overview
Service object: confirm message processor.
Constant Summary collapse
- ACKNOWLEDGE_MESSAGE_PARTNERS =
NOT dead code, despite reading that way: this is the gate that keeps the
acknowledge message OFF. No CommerceHub partner we run today
(costco / thdca / thehomedepot / rona) requires it — only Lowe's US did,
and that partner is no longer configured. Dropping the guard would start
sending acknowledgements to all four. Add a partner here to turn it on. ['lowes'].freeze
Constants included from RequestIdentifiable
RequestIdentifiable::REQUEST_ID_HEADERS
Constants included from AddressAbbreviator
AddressAbbreviator::MAX_LENGTH
Instance Attribute Summary
Attributes inherited from BaseEdiService
Attributes inherited from BaseService
Instance Method Summary collapse
-
#acknowledge_order(order, options = {}) ⇒ EdiCommunicationLog?
The created log.
- #auto_cancel_order(order, order_hash, reason_code, _bad_vendor_skus = nil, _bad_merchant_skus = nil) ⇒ Object
- #auto_reject_order(order, order_hash, reason_code, _bad_vendor_skus = nil, _bad_merchant_skus = nil) ⇒ Object
-
#back_order(order, options = {}) ⇒ EdiCommunicationLog?
The created log.
- #build_acknowledge_message_from_order(order) ⇒ Object
- #build_acknowledge_reject_message_from_order_hash(order, order_hash, reason_code) ⇒ Object
- #build_back_order_message_from_order(order) ⇒ Object
- #build_cancel_message_from_order(order) ⇒ Object
- #build_cancel_message_from_order_hash(order, order_hash, _reason_code) ⇒ Object
- #build_confirm_message_from_invoice(invoice) ⇒ Object
-
#cancel_order(order, options = {}) ⇒ EdiCommunicationLog?
The created log.
-
#confirm_invoice(invoice, options = {}) ⇒ EdiCommunicationLog?
The created log.
- #get_ship_code_from_invoice(invoice) ⇒ Object
-
#process(confirm_message, options) ⇒ EdiCommunicationLog
Picks up the edi communication log in the queue ready to process, generate confirms.
-
#process_acknowledgement(acknowledgement_message, options) ⇒ EdiCommunicationLog
The created log.
Methods inherited from BaseEdiService
#amazon_feed_product_type, #duplicate_po_already_notified?, #initialize, #mark_duplicate_po_as_notified, #onboard_ordered_catalog_items, #report_order_creation_issues, #safe_process_edi_communication_log
Methods included from RequestIdentifiable
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, #tagged_logger
Constructor Details
This class inherits a constructor from Edi::BaseEdiService
Instance Method Details
#acknowledge_order(order, options = {}) ⇒ EdiCommunicationLog?
Returns the created log.
204 205 206 207 208 209 210 |
# File 'app/services/edi/commercehub/confirm_message_processor.rb', line 204 def acknowledge_order(order, = {}) # only send this for those partners that support/require it return unless ACKNOWLEDGE_MESSAGE_PARTNERS.include?(orchestrator.ch_partner_id) m = (order) process_acknowledgement(m, .merge({ order: order })) end |
#auto_cancel_order(order, order_hash, reason_code, _bad_vendor_skus = nil, _bad_merchant_skus = nil) ⇒ Object
221 222 223 224 |
# File 'app/services/edi/commercehub/confirm_message_processor.rb', line 221 def auto_cancel_order(order, order_hash, reason_code, _bad_vendor_skus = nil, _bad_merchant_skus = nil) m = (order, order_hash, reason_code) process(m, .merge({ order: order })) end |
#auto_reject_order(order, order_hash, reason_code, _bad_vendor_skus = nil, _bad_merchant_skus = nil) ⇒ Object
226 227 228 229 |
# File 'app/services/edi/commercehub/confirm_message_processor.rb', line 226 def auto_reject_order(order, order_hash, reason_code, _bad_vendor_skus = nil, _bad_merchant_skus = nil) m = (order, order_hash, reason_code) process_acknowledgement(m, .merge({ order: order })) end |
#back_order(order, options = {}) ⇒ EdiCommunicationLog?
Returns the created log.
235 236 237 238 239 240 |
# File 'app/services/edi/commercehub/confirm_message_processor.rb', line 235 def back_order(order, = {}) return if orchestrator.ignore_back_orders m = (order) process(m, .merge({ order: order })) end |
#build_acknowledge_message_from_order(order) ⇒ Object
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 |
# File 'app/services/edi/commercehub/confirm_message_processor.rb', line 74 def (order) line_items = order.line_items.non_shipping.where.not(edi_reference: nil).order(:edi_line_number) msg = Edi::Commercehub::ConfirmMessage.new msg.ch_partner_id = orchestrator.ch_partner_id msg.ch_partner_name = orchestrator.ch_partner_name msg.ch_vendor_id = orchestrator.ch_vendor_id msg.trx_id = order.reference_number msg.trx_date = order.created_at msg.po_number = order.first_po_number msg.order_date = order.created_at msg.lines = [] line_items.each do |li| new_line = Edi::Commercehub::ConfirmMessage::MerchantLine.new( action: 'accept', action_code: nil, trx_id: li.edi_reference, line_number: li.edi_line_number, trx_qty: li.quantity ) msg.lines << new_line end msg end |
#build_acknowledge_reject_message_from_order_hash(order, order_hash, reason_code) ⇒ Object
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 |
# File 'app/services/edi/commercehub/confirm_message_processor.rb', line 101 def (order, order_hash, reason_code) order_xml = Nokogiri::XML(order_hash[:xml]).xpath('hubOrder') msg = Edi::Commercehub::ConfirmMessage.new msg.ch_partner_id = orchestrator.ch_partner_id msg.ch_partner_name = orchestrator.ch_partner_name msg.ch_vendor_id = orchestrator.ch_vendor_id msg.trx_id = order.reference_number msg.trx_date = Date.parse(order_xml.xpath('orderDate').text) msg.po_number = order_xml.xpath('poNumber').text msg.order_date = Date.parse(order_xml.xpath('orderDate').text) msg.lines = [] order_xml.xpath('lineItem').each do |line_xml| # merchant_sku = line_xml.xpath('merchantSKU')&.text # vendor_sku = line_xml.xpath('vendorSKU')&.text new_line = Edi::Commercehub::ConfirmMessage::MerchantLine.new( action: 'reject', action_code: reason_code, trx_id: line_xml.xpath('lineItemId').text, line_number: line_xml.xpath('merchantLineNumber').text, trx_qty: line_xml.xpath('qtyOrdered').text.to_i ) msg.lines << new_line end msg end |
#build_back_order_message_from_order(order) ⇒ Object
173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'app/services/edi/commercehub/confirm_message_processor.rb', line 173 def (order) msg = Edi::Commercehub::ConfirmMessage.new msg.ch_partner_id = orchestrator.ch_partner_id msg.ch_partner_name = orchestrator.ch_partner_name msg.trx_id = order.reference_number msg.trx_date = order.created_at msg.po_number = order.first_po_number msg.order_date = order.created_at msg.lines = order.line_items.where.not(edi_reference: nil).order(:edi_line_number).map do |li| Edi::Commercehub::ConfirmMessage::MerchantLine.new( action: 'v_backorder', trx_id: li.edi_reference, line_number: li.edi_line_number, trx_qty: li.quantity, expected_date: 5.days.from_now.to_date ) end msg end |
#build_cancel_message_from_order(order) ⇒ Object
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
# File 'app/services/edi/commercehub/confirm_message_processor.rb', line 129 def (order) msg = Edi::Commercehub::ConfirmMessage.new msg.ch_partner_id = orchestrator.ch_partner_id msg.ch_partner_name = orchestrator.ch_partner_name msg.trx_id = order.reference_number msg.trx_date = order.created_at msg.po_number = order.first_po_number msg.order_date = order.created_at msg.lines = order.line_items.where.not(edi_reference: nil).order(:edi_line_number).map do |li| Edi::Commercehub::ConfirmMessage::MerchantLine.new( action: 'v_cancel', action_code: order.cancellation_reason.presence || 'merchant_request', trx_id: li.edi_reference, line_number: li.edi_line_number, trx_qty: li.quantity ) end msg end |
#build_cancel_message_from_order_hash(order, order_hash, _reason_code) ⇒ Object
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'app/services/edi/commercehub/confirm_message_processor.rb', line 149 def (order, order_hash, _reason_code) order_xml = Nokogiri::XML(order_hash[:xml]).xpath('hubOrder') msg = Edi::Commercehub::ConfirmMessage.new msg.ch_partner_id = orchestrator.ch_partner_id msg.ch_partner_name = orchestrator.ch_partner_name msg.trx_id = order.reference_number msg.trx_date = Date.parse(order_xml.xpath('orderDate').text) msg.po_number = order_xml.xpath('poNumber').text msg.order_date = Date.parse(order_xml.xpath('orderDate').text) order_xml.xpath('lineItem').each do |line_xml| # merchant_sku = line_xml.xpath('merchantSKU')&.text # vendor_sku = line_xml.xpath('vendorSKU')&.text new_line = Edi::Commercehub::ConfirmMessage::MerchantLine.new( action: 'v_cancel', action_code: order.cancellation_reason.presence || 'merchant_request', trx_id: line_xml.xpath('lineItemId').text, line_number: line_xml.xpath('merchantLineNumber').text, trx_qty: line_xml.xpath('qtyOrdered').text.to_i ) msg.lines << new_line end msg end |
#build_confirm_message_from_invoice(invoice) ⇒ Object
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 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 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 'app/services/edi/commercehub/confirm_message_processor.rb', line 6 def (invoice) shipments = invoice.delivery.shipments.completed line_items = invoice.delivery.line_items.where.not(edi_reference: nil).order(:edi_line_number) msg = Edi::Commercehub::ConfirmMessage.new msg.ch_partner_id = orchestrator.ch_partner_id msg.ch_partner_name = orchestrator.ch_partner_name msg.vendor_warehouse_id = orchestrator.vendor_warehouse_id if orchestrator.try(:vendor_warehouse_id).present? msg.trx_id = invoice.order.reference_number msg.trx_date = invoice.order.created_at msg.po_number = invoice.order.first_po_number msg.order_date = invoice.order.created_at # If we send an invoice to CH, we don't do it here msg.invoice_number = invoice.reference_number unless orchestrator. oa = invoice.delivery.origin_address vendor_ship_info = Edi::Commercehub::ConfirmMessage::VendorShipInfo.new( vendor_ship_id: oa.id, name1: oa.company_name, address1: oa.street1, address2: oa.street2, address3: oa.street3, city: oa.city, state: oa.state_code, country: oa.country_iso3, postal_code: oa.zip ) msg.vendor_ship_infos << vendor_ship_info msg.packages = shipments.non_pallets.completed.map do |shp| Edi::Commercehub::ConfirmMessage::Package.new( package_id: shp.reference_number, pallet_id: shp.parent_shipment&.reference_number, length: shp.length, width: shp.width, height: shp.height, weight: shp.weight, service_level: get_ship_code_from_invoice(invoice), tracking_number: shp.tracking_number || invoice.delivery.master_tracking_number || invoice.delivery.carrier_bol, ship_date: shp.date_shipped, vendor_ship_info: vendor_ship_info ) end msg.lines = [] line_items.each do |li| if (shipment_contents = li.shipment_contents.from_completed_shipments).present? # Lines were allocated to shipments shipment_contents.each do |shipment_content| msg.lines << Edi::Commercehub::ConfirmMessage::MerchantLine.new( action: 'v_ship', trx_id: li.edi_reference, line_number: li.edi_line_number, trx_qty: shipment_content.quantity, package: msg.packages.find { |p| p.package_id == shipment_content.shipment.reference_number }, serial_numbers: li.serial_numbers.map(&:number) ) end else # We don't know which line is in which box, so take the first package msg.lines << Edi::Commercehub::ConfirmMessage::MerchantLine.new( action: 'v_ship', trx_id: li.edi_reference, line_number: li.edi_line_number, trx_qty: li.quantity, package: msg.packages.first, serial_numbers: li.serial_numbers.map(&:number) ) end end msg end |
#cancel_order(order, options = {}) ⇒ EdiCommunicationLog?
Returns the created log.
216 217 218 219 |
# File 'app/services/edi/commercehub/confirm_message_processor.rb', line 216 def cancel_order(order, = {}) m = (order) process(m, .merge({ order: order })) end |
#confirm_invoice(invoice, options = {}) ⇒ EdiCommunicationLog?
Returns the created log.
246 247 248 249 |
# File 'app/services/edi/commercehub/confirm_message_processor.rb', line 246 def confirm_invoice(invoice, = {}) m = (invoice) process(m, .merge({ order: invoice.order })) end |
#get_ship_code_from_invoice(invoice) ⇒ Object
377 378 379 380 381 382 383 384 |
# File 'app/services/edi/commercehub/confirm_message_processor.rb', line 377 def get_ship_code_from_invoice(invoice) shipping_method_name = invoice.delivery.shipping_option.name if shipping_method_name.downcase.include?('override') # handle override shipping to just match the original and don;t bother with mappings invoice.delivery.order.edi_original_ship_code else orchestrator.ship_code_mapper.hw_to_ch(shipping_method_name, signature: invoice.delivery.signature_confirmation, saturday: invoice.delivery.saturday_delivery) end end |
#process(confirm_message, options) ⇒ EdiCommunicationLog
Picks up the edi communication log in the queue ready to process, generate confirms
257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 |
# File 'app/services/edi/commercehub/confirm_message_processor.rb', line 257 def process(, ) order = [:order] transmit_after = [:transmit_after] b = Nokogiri::XML::Builder.new do |xml| xml.send(:ConfirmMessageBatch) do xml.send(:partnerID, .ch_partner_id) xml.send(:hubConfirm) do participating_party_attributes = { roleType: 'merchant', participationCode: 'To:' } participating_party_attributes[:name] = .ch_partner_id xml.send(:participatingParty, .ch_partner_id, participating_party_attributes) xml.send(:partnerTrxID, .trx_id) xml.send(:partnerTrxDate, .trx_date.strftime('%Y%m%d')) xml.send(:poNumber, .po_number) if .invoice_number xml.send(:trxData) do xml.send(:orderDate, .order_date.strftime('%Y%m%d')) xml.send(:vendorsInvoiceNumber, .invoice_number) end end .lines.each do |li| hub_action_attributes = {} hub_action_attributes[:transactionItemID] = li.trx_id xml.send(:hubAction, hub_action_attributes) do xml.send(:action, li.action) xml.send(:actionCode, li.action_code) if li.action_code xml.send(:merchantLineNumber, li.line_number) xml.send(:trxQty, li.trx_qty) xml.send(:expectedDate, li.expected_date.strftime('%Y%m%d')) if li.expected_date xml.send(:packageDetailLink, packageDetailID: "ID#{li.package.package_id}") if li.package if .ch_partner_id == 'costco' && li.serial_numbers.any? li.serial_numbers.each do |sn| xml.send(:serialNumber, sn) end end if .ch_partner_id == 'costco' && .vendor_warehouse_id.present? xml.send(:trxItemData) do xml.send(:vendorWarehouseId, .vendor_warehouse_id) end end end end .packages.each do |pkg| xml.send(:packageDetail, packageDetailID: "ID#{pkg.package_id}") do xml.send(:shipDate, pkg.ship_date.strftime('%Y%m%d')) xml.send(:serviceLevel1, pkg.service_level) xml.send(:trackingNumber, pkg.tracking_number) xml.send(:shipFrom, vendorShipID: pkg.vendor_ship_info.vendor_ship_id) if pkg.vendor_ship_info end end .vendor_ship_infos.each do |vsi| xml.send(:vendorShipInfo, vendorShipID: vsi.vendor_ship_id) do xml.send :name1, vsi.name1 xml.send :address1, vsi.address1 xml.send :address2, vsi.address2 xml.send :address3, vsi.address3 xml.send :city, vsi.city xml.send :state, vsi.state xml.send :country, vsi.country xml.send :postalCode, vsi.postal_code end end end end end EdiCommunicationLog.create_outbound_file_from_data(data: b.to_xml, file_extension: 'confirm', partner: orchestrator.partner, category: 'order_confirm', data_type: 'xml', transmit_after: transmit_after, resources: order, file_info: { lines_confirmed: .lines.size, packages: .packages.size }) end |
#process_acknowledgement(acknowledgement_message, options) ⇒ EdiCommunicationLog
Returns the created log.
336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 |
# File 'app/services/edi/commercehub/confirm_message_processor.rb', line 336 def process_acknowledgement(, ) order = [:order] transmit_after = [:transmit_after] b = Nokogiri::XML::Builder.new do |xml| xml.send(:PO_Acknowledgements, 'batch-number': 1) do xml.send(:partnerID, .ch_partner_id) xml.send(:PO_Acknowledgement, 'ack-type': 'initial') do xml.send(:messageControlNumber, .trx_id) xml.send(:originatingSystemTrxId, .trx_id, trxDate: .trx_date.strftime('%Y%m%d')) xml.send(:participatingParty, .ch_partner_id, role: 'merchant', participationCode: 'To:') xml.send(:poNumber, .po_number) xml.send(:scheduledShipDate, order.get_scheduled_ship_date_time.strftime('%Y%m%d')) .lines.each do |li| xml.send(:lineitem_ack) do xml.send(:poLineNumber, li.line_number) xml.send(:quantityOpen, li.trx_qty) xml.send(:action) do xml.send(:quantity, li.trx_qty) if %w[reject backorder].include?(li.action) # sigh, they use the backorder element for reject, sheesh, a real hacky thing but it is what it is... xml.send(:backorder, li.trx_qty, 'backorder-reason': li.action_code) else xml.send(:accept) end end end end end xml.send(:messageCount, 1) end end EdiCommunicationLog.create_outbound_file_from_data(data: b.to_xml, file_extension: 'acknowledge', partner: orchestrator.partner, category: 'order_acknowledge', data_type: 'xml', resources: order, transmit_after: transmit_after, file_info: { lines_confirmed: .lines.size }) end |