Class: Edi::Commercehub::InvoiceMessageProcessor
- Inherits:
-
BaseEdiService
- Object
- BaseService
- BaseEdiService
- Edi::Commercehub::InvoiceMessageProcessor
- Defined in:
- app/services/edi/commercehub/invoice_message_processor.rb
Constant Summary
Constants included from AddressAbbreviator
AddressAbbreviator::MAX_LENGTH
Instance Attribute Summary
Attributes inherited from BaseEdiService
Instance Method Summary collapse
- #build_invoice_message_from_invoice(invoice) ⇒ Object
- #create_invoice(invoice, options = {}) ⇒ Object
- #get_ship_code_from_invoice(invoice) ⇒ Object
-
#process(confirm_message, options = {}) ⇒ Object
Picks up the edi communication log in the queue ready to process, generate acknowledgements.
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
#build_invoice_message_from_invoice(invoice) ⇒ Object
5 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 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 |
# File 'app/services/edi/commercehub/invoice_message_processor.rb', line 5 def (invoice) shipments = invoice.delivery.shipments.completed line_items = invoice.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 = invoice.reference_number msg.trx_date = invoice.gl_date if msg.ch_partner_id == 'thehomedepot' # TEMPORARY PATCH TO GET 1/31/24 TAX EXPIRATION/REJECTED INVOICE MESSAGES RESUBMITTED msg.trx_tax = 0.0 else msg.trx_tax = invoice.tax_total unless msg.ch_partner_id == 'rona' # according to XSD end msg.po_number = invoice.order.first_po_number msg.order_date = invoice.order.created_at msg.invoice_number = invoice.reference_number msg.trx_currency = invoice.currency msg.trx_balance_due = if msg.ch_partner_id == 'thehomedepot' # TEMPORARY PATCH TO GET 1/31/24 TAX EXPIRATION/REJECTED INVOICE MESSAGES RESUBMITTED invoice.amount_due - invoice.tax_total else invoice.amount_due end msg.net_days_due = invoice.terms_in_days msg.tax_exempt_number = orchestrator.tax_exempt_number if orchestrator.respond_to?(:tax_exempt_number) # Except for Rona, per XSD no CommerceHub partner XSD requires this in the invoice message ... let's skip it entirely, 8/13/19 - Ramie # Let;s try to also do this for THDCA if %w[thdca rona].include?(msg.ch_partner_id) ch_tax_types = { gst: 'CG', qst: 'ST', hst: 'VA' }.with_indifferent_access invoice.taxes_grouped_by_type.each do |type, details| msg.tax_breakouts << Edi::Commercehub::ConfirmMessage::TaxBreakout.new( tax_type: ch_tax_types[type], currency_unit: invoice.currency, amount: details[:tax_amount] ) end end if invoice.early_payment_discount && invoice.early_payment_due_date msg.payment_discount_breakouts << Edi::Commercehub::ConfirmMessage::PaymentDiscountBreakout.new( percent: invoice.early_payment_discount, due_date: invoice.early_payment_due_date, days_due: invoice.discount_days_due, net_due_date: invoice.due_date, net_days_due: invoice.terms_in_days ) end msg.invoice_remit_id = orchestrator.invoice_remit_id msg.packages = shipments.map do |shp| Edi::Commercehub::ConfirmMessage::Package.new( package_id: shp.reference_number, 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 ) end msg.lines = [] line_items.each do |li| new_line = Edi::Commercehub::ConfirmMessage::MerchantLine.new( action: 'v_invoice', trx_id: li.edi_reference, line_number: li.edi_line_number, trx_qty: li.quantity, trx_unit_cost: li.discounted_price, # let's try making tax at the total invoice level for THDCA rather than break it out because some partner XSDs have no reference to line tax, but do keep it for Rona which requires tax broken down at the line level trx_line_tax: (msg.ch_partner_id == 'rona' ? li.tax_total : nil), # this will be line balance without taxes, except for rona which should include taxes trx_line_balance_due: (msg.ch_partner_id == 'rona' ? li.line_total_with_tax : li.discounted_total) ) if msg.ch_partner_id == 'rona' li.taxes_grouped_by_type.each do |type, details| new_line.tax_breakouts << Edi::Commercehub::ConfirmMessage::TaxBreakout.new( tax_type: ch_tax_types[type], currency_unit: invoice.currency, amount: details[:tax_amount] ) end end if (shipment_contents = li.shipment_contents.from_completed_shipments).present? # Lines were allocated to shipments shipment_contents.each do |shipment_content| new_line.package = msg.packages.detect { |p| p.package_id == shipment_content.shipment.reference_number } end else # We don't know which line is in which box, so take the first package new_line.package = msg.packages.first end msg.lines << new_line end msg end |
#create_invoice(invoice, options = {}) ⇒ Object
101 102 103 104 |
# File 'app/services/edi/commercehub/invoice_message_processor.rb', line 101 def create_invoice(invoice, = {}) m = (invoice) process(m, .merge({ order: invoice.order, invoice: invoice })) end |
#get_ship_code_from_invoice(invoice) ⇒ Object
204 205 206 207 208 209 210 211 |
# File 'app/services/edi/commercehub/invoice_message_processor.rb', line 204 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 = {}) ⇒ Object
Picks up the edi communication log in the queue ready to process, generate acknowledgements
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 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 |
# File 'app/services/edi/commercehub/invoice_message_processor.rb', line 107 def process(, = {}) order = [:order] transmit_after = [:transmit_after] b = Nokogiri::XML::Builder.new do |xml| args = (.ch_partner_id == 'rona' ? { batchNumber: '1' } : {}) xml.send(:InvoiceMessageBatch, args) do args = (.ch_partner_id == 'rona' ? {} : { name: 'WarmlyYours Radiant', roleType: 'vendor' }) xml.send(:partnerID, .ch_vendor_id, args) xml.send(:hubInvoice) do xml.send(:participatingParty, .ch_partner_id, name: .ch_partner_name, roleType: 'merchant', participationCode: 'To:') xml.send(:partnerTrxID, .trx_id) xml.send(:partnerTrxDate, .trx_date.strftime('%Y%m%d')) xml.send(:poNumber, .po_number) # according to XSDs, only thdca and rona specify trxCurrency xml.send(:trxCurrency, .trx_currency) if %w[thdca rona lowes].include?(.ch_partner_id) xml.send(:trxTax, .trx_tax) if .trx_tax.present? xml.send(:trxBalanceDue, .trx_balance_due) # adding it back to thehomedepot because it needs the net60 terms # per XSD no CommerceHub partner XSD requires this in the invoice message ... let's skip it entirely, 8/13/19 - Ramie # per customersupport@commercehub.com on 8/7/2019 - Ramie if %w[thehomedepot thdca lowes].include?(.ch_partner_id) xml.send(:trxData) do # per customersupport@commercehub.com on 8/7/2019 - Ramie if .ch_partner_id == 'thdca' .tax_breakouts.each do |tb| xml.send(:taxBreakout, tb.amount, taxType: tb.tax_type, currencyUnit: tb.currency_unit) end end if %w[thehomedepot lowes].include?(.ch_partner_id) if .payment_discount_breakouts.present? .payment_discount_breakouts.each do |pdb| xml.send(:discountBreakout, discPercent: pdb.percent, discDueDate: pdb.due_date.strftime('%Y%m%d'), discDaysDue: pdb.days_due, netDueDate: pdb.net_due_date&.strftime('%Y%m%d'), netDaysDue: pdb.net_days_due) end elsif .net_days_due # For some reason this gets shoved in the same discount breakout xml.send(:discountBreakout, netDaysDue: .net_days_due) end end end end .lines.each do |li| xml.send(:hubAction) do xml.send(:action, li.action) xml.send(:merchantLineNumber, li.line_number) xml.send(:trxQty, li.trx_qty) xml.send(:trxUnitCost, li.trx_unit_cost) xml.send(:trxLineTax, li.trx_line_tax) if li.trx_line_tax.present? # according to XSDs, only thdca and rona specify trxLineBalanceDue # let's try making tax at the total invoice level rather than break it out because some partner XSDs have no reference to line tax xml.send(:trxLineBalanceDue, li.trx_line_balance_due) if %w[thdca rona].include?(.ch_partner_id) xml.send(:invoiceDetailLink, invoiceDetailID: .trx_id) # per XSD except for rona, no CommerceHub partner XSD requires this in the invoice message ... let's skip it entirely, 8/13/19 - Ramie if .ch_partner_id == 'rona' xml.send(:trxItemData) do li.tax_breakouts.each do |tb| xml.send(:taxBreakout, tb.amount, taxType: tb.tax_type) end end end # according to XSDs, thehomedepot specifies packageDetailLink xml.send(:packageDetailLink, packageDetailID: "PK#{li.package.package_id}") if .ch_partner_id == 'thehomedepot' and li.package end end xml.send(:invoiceDetail, invoiceDetailID: .trx_id) do xml.send(:remitTo, personPlaceID: 'PP0000000001') # according to XSD end if .ch_partner_id == 'thehomedepot' and .lines.select { |li| li.package.present? }.any? .lines.select { |li| li.package.present? }.each do |li| xml.send(:packageDetail, packageDetailID: "PK#{li.package.package_id}") do xml.send(:shipDate, li.package.ship_date.strftime('%Y%m%d')) xml.send(:serviceLevel1, li.package.service_level) xml.send(:trackingNumber, li.package.tracking_number) end end end xml.send(:personPlace, personPlaceID: 'PP0000000001') do # according to XSD if .ch_partner_id == 'rona' xml.send(:personPlaceData) do xml.send(:taxExemptNumber, .tax_exempt_number) end end xml.send(:partnerPersonPlaceId, .invoice_remit_id) end end xml.send(:messageCount, 1) # according to XSD end end invoice = [:invoice] EdiCommunicationLog.create_outbound_file_from_data(data: b.to_xml, file_extension: 'invoice', partner: orchestrator.partner, category: 'invoice', data_type: 'xml', resources: invoice || order, transmit_after: transmit_after, file_info: { lines_confirmed: .lines.size, packages: .packages.size }) end |