Class: OrderPresenter

Inherits:
BasePresenter show all
Includes:
Presenters::StandardOperationsForRecord
Defined in:
app/presenters/order_presenter.rb

Instance Attribute Summary

Attributes inherited from BasePresenter

#current_account, #options, #url_helper

Instance Method Summary collapse

Methods inherited from BasePresenter

#can?, #capture, #concat, #content_tag, #fa_icon, #h, #initialize, #link_to, #number_to_currency, #present, presents, #r, #safe_present, #simple_format, #u

Constructor Details

This class inherits a constructor from BasePresenter

Instance Method Details

#actions(return_path: nil, warehouse_context: nil) ⇒ Object



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
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
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/presenters/order_presenter.rb', line 162

def actions(return_path: nil, warehouse_context: nil)
  actions_list = []
  return_path ||= h.order_path(order)

  if cancelled?
    actions_list << h.link_to('Restore', h.restore_order_path(order, return_path: return_path), data: { turbo_method: :post })
    if h.user_has_role?('admin') || ok_to_delete?
      actions_list << h.link_to('Delete', h.order_path(order, return_path: return_path),
                                data: { turbo_method: :delete, turbo_confirm: 'Are you sure want to delete this order?' })
    end
  else
    actions_list << h.link_to(fa_icon('pencil', text: 'Edit Order'), h.(order, return_path: return_path)) unless editing_locked?

    if h.can?(:manage_profit_margins, order) && order.track_profit?
      actions_list << link_to(fa_icon('chart-pie', text: 'Review/Update Profit Margins'),
                              h.profit_margins_order_path(order))
    end

    if !in_cr_hold? && can_cr_hold?(h.current_user)
      cr_hold_confirm = h.prepurchased_label_void_confirm(order)
      cr_hold_data = { turbo_method: :post }
      cr_hold_data[:turbo_confirm] = cr_hold_confirm if cr_hold_confirm
      actions_list << h.link_to(h.fa_icon('person-sign', text: 'CR Hold (and reserve stock)'),
                                h.place_cr_hold_order_path(order, reserve_stock: '1', return_path: return_path), data: cr_hold_data)
      actions_list << h.link_to(h.fa_icon('person-sign', text: 'CR Hold (and DO NOT reserve stock)', family: 'fas'),
                                h.place_cr_hold_order_path(order, return_path: return_path), data: cr_hold_data)
    end

    if (pending? || cart? || pending_payment? || crm_back_order? || in_cr_hold?) && !is_store_transfer?
      actions_list << h.link_to(h.fa_icon('axe', text: 'Split Order'), h.split_order_path(order, return_path: return_path)) # NEVER EVER EVER split an ST
    end

    if pending? || cart?
      actions_list << if customer.guest?
                        h.link_to('Edit Customer', h.edit_customer_path(customer_id, return_path: h.customer_path(customer_id, tab: 'duplicates')))
                      else
                        h.link_to(fa_icon('rocket', text: 'Process Order'), h.(order))
                      end
    elsif pending_payment?
      if h.can?(:place_orders, customer)
        actions_list << h.link_to('Skip Payment', h.skip_payment_order_payments_path(order)) if order.balance == 0
        actions_list << h.link_to(fa_icon('skull', text: 'Force Invoiced Status'), h.force_invoiced_status_order_path(order)) if h.user_has_role?('admin')
        actions_list << h.link_to(fa_icon('money-bill', text: 'Enter Payment'), h.new_order_payment_path(order))
      end
      actions_list << h.link_to(fa_icon('thumbtack', text: 'Back Order Entire Order'), h.split_back_order_all_order_path(order, return_path: return_path))
    elsif pending_release_authorization?
      if h.user_has_role?('order_authorizer')
        actions_list << if potential_fraud?
                          h.render(partial: 'orders/workflow_action', locals: { order: self, link_text: 'Mark Order as Fraudulent', wf_action: 'mark_as_fraudulent', confirm: true,
                                                                               confirm_text: h.prepurchased_label_void_confirm(order, 'Are you sure?') })
                        else
                          h.render(partial: 'orders/workflow_action', locals: { order: self, link_text: 'Deny Release', wf_action: 'deny_order', confirm: true,
                                                                               confirm_text: h.prepurchased_label_void_confirm(order, 'Are you sure?') })
                        end
      end
      if h.user_has_role?(%w[accounting_rep order_authorizer]) && !payments.paypal_invoices.all_authorized.exists?
        actions_list << h.render(partial: 'orders/workflow_action', locals: { order: self, link_text: 'Authorize and Release', wf_action: 'release_order' })
      end
    elsif crm_back_order?
      actions_list << h.link_to(fa_icon('money-bill', text: 'Enter Payment'), h.new_order_payment_path(order)) unless order.balance.zero?
      actions_list << h.link_to(fa_icon('rocket', text: 'Release Back Order'), h.release_back_order_order_path(order, return_path: return_path), data: { turbo_method: :post }) if everything_in_stock?
    elsif in_cr_hold?
      actions_list << h.link_to(h.fa_icon('rocket', text: 'Release CR Hold'), h.release_cr_hold_order_path(order, return_path: return_path), data: { turbo_method: :post })
      actions_list << h.link_to(h.fa_icon('truck-container', text: 'Back Order Entire Order'), h.split_back_order_all_order_path(order, return_path: return_path))
    elsif partially_shipped? && !service_only_order?
      unless is_warehouse_pickup?
        actions_list << h.link_to('Resend Tracking E-mail', h.send_tracking_email_order_path(order, return_path: return_path),
                                  data: { turbo_confirm: "Are you sure? This will re-send the tracking information to the order's identified tracking emails." })
      end
      if is_warehouse_pickup?
        actions_list << h.link_to('Resend Order Ready For Pickup E-mail', h.send_tracking_email_order_path(order, return_path: return_path),
                                  data: { turbo_confirm: "Are you sure? This will re-send the ready for pickup information to the order's identified tracking emails." })
      end
    elsif in_management_hold? && h.user_is_manager?
      actions_list << h.link_to('Release Management Hold', h.release_management_hold_order_path(order, return_path: return_path), data: { turbo_method: :post })
    end

    actions_list << h.link_to('Mark Service Only Order As Shipped', h.ship_confirm_service_deliveries_order_path(order, return_path: return_path), data: { turbo_method: :post }) if service_only_order? && deliveries.any?(&:service_ready_to_fulfill?)

    if pending_review?
      actions_list << h.render(partial: 'orders/workflow_action', locals: { order: self, link_text: 'Approve', wf_action: 'approved', block_ui: true })
    elsif ready_for_printing?
      actions_list << h.render(partial: 'orders/workflow_action', locals: { order: self, link_text: 'Print Credit Memo', wf_action: 'print_credit_memo', block_ui: true })
    end

    # Review request link removed
    # pr_action = reviews.any? ? 'Resend' : 'Send'
    # actions_list << h.link_to("#{pr_action} Review Request", h.resend_review_request_order_path(order), method: :post, data: { confirm: "#{pr_action}ing Review Request for this order to customer, continue?" }) if invoiced?

    actions_list << h.link_to('Resend conversion to Google', h.resend_google_offline_conversion_order_path(order, return_path: return_path), data: { turbo_method: :post }) if invoiced?

    actions_list << h.link_to('Edit Sales Support Rep', h.edit_sales_support_rep_order_path(order, return_path: return_path)) if h.can?(:edit_sales_support_rep,
order) && (order.sales_support_commission_date.nil? || order.sales_support_commission_date > Date.today)

    actions_list << if order.exclude_from_payment_check
                      h.link_to('Include in Payment Check', h.include_in_payment_check_order_path(order, return_path: return_path), data: { turbo_method: :post })
                    else
                      h.link_to('Exclude from Payment Check', h.exclude_from_payment_check_order_path(order, return_path: return_path), data: { turbo_method: :post })
                    end

    if needs_serial_number_reservation?
      actions_list << if line_items.all? { |li| !li.require_reservation? }
                        h.link_to('Cancel serial number reservation', h.release_back_order_order_path(order, return_path: return_path), data: { turbo_method: :post })
                      else
                        h.link_to(h.fa_icon('list-ol', text: 'Pick Serial Numbers'), h.pick_serial_numbers_order_path(order, return_path: return_path))
                      end
    end

    actions_list << h.link_to(h.fa_icon('cubes', text: 'Reserve/unreserve stock'), h.pick_lines_inventory_commits_path(resource_type: 'Order', resource_id: order.id, return_path: return_path)) if can_be_committed? || can_be_uncommitted?

    actions_list << h.link_to(fa_icon('rocket', text: 'Move Order'), h.move_order_path(order, return_path: return_path)) if Order::Mover.order_moveable?(order)

    actions_list << h.link_to(h.fa_icon('barcode-read', text: 'Print UPC Labels'), h.generate_barcodes_path(order_id: order.id, return_path: return_path))

    order.deliveries.active.each_with_index do |delivery, idx|
      if delivery.can_print_carton_labels?
        actions_list << h.link_to("Print Carton/UCC-128 Labels #{idx + 1 if idx > 1}", h.generate_carton_labels_path(delivery_id: delivery.id, return_path: return_path), class: 'dropdown-item')
      end
    end

    unless editing_locked?
      future_release_path = h.edit_release_date_delivery_path(order.deliveries.for_future_release.first, return_path: return_path) if order.can_edit_future_release_date?
      edit_address_path = h.shipping_address_order_path(order, return_path: return_path)
      edit_shipping_method_path = h.shipping_order_path(order, return_path: return_path)

      actions_list << h.link_to(h.fa_icon('map-marker-alt', text: 'Edit Shipping Address'), edit_address_path) unless order.pre_pack?
      actions_list << h.link_to(h.fa_icon('truck', text: 'Edit Shipping Method'), edit_shipping_method_path) unless order.pre_pack?
      actions_list << h.link_to(h.fa_icon('calendar-edit', text: 'Edit Release Date'), future_release_path) if future_release_path
      pp_disabled = (show_order_pre_pack_option(order) ? false : true)
      if order.can_request_estimated_packaging?
        actions_list << h.link_to(h.fa_icon('box-check', text: "#{pp_disabled ? 'Already packaged, contact Warehouse to request repackaging' : 'Request Estimated Packaging'}"),
                                  (pp_disabled ? 'javascript:void(0);' : workflow_action_url('request_estimated_packaging', return_path:, warehouse_context:)))
      end
      actions_list << order_workflow_link(h.fa_icon('box-full', text: 'Cancel Estimated Packaging Request'), 'cancel_packaging_request', return_path:, warehouse_context:) if order.can_cancel_packaging_request?
      actions_list << order_workflow_link(h.fa_icon('truck-moving', text: 'Request Carrier Assignment'), 'request_carrier_assignment', return_path:, warehouse_context:) if order.can_request_carrier_assignment?
      actions_list << order_workflow_link(h.fa_icon('truck-moving', text: 'Wait for Carrier Assignment'), 'wait_for_carrier_assignment', return_path:, warehouse_context:) if order.can_wait_for_carrier_assignment?
      actions_list << order_workflow_link(h.fa_icon('truck-loading', text: 'Cancel Carrier Assignment/CR Hold'), 'cancel_carrier_assignment', return_path:, warehouse_context:) if order.can_cancel_carrier_assignment?

      unless order.order_type == Order::CREDIT_ORDER
        if order.billing_entity.can_pay_by_cod_business_check || order.billing_entity.has_terms?
          actions_list << if order.cod_collection_type == 'check'
                            h.link_to(fa_icon('ban', text: 'Cancel COD (check)'), h.cancel_cod_check_order_path(order.id, customer_id: order.customer.id, return_path: return_path))
                          else
                            h.link_to(fa_icon('money-check-alt', text: 'Switch to COD (check)'), h.cod_check_order_path(order.id, customer_id: order.customer.id, return_path: return_path))
                          end
        end
        actions_list << if order.cod_collection_type == 'no_check'
                          h.link_to(fa_icon('money-check', text: 'Cancel COD (certified)'), h.cancel_cod_no_check_order_path(order.id, customer_id: order.customer_id, return_path: return_path))
                        else
                          h.link_to(fa_icon('money-check', text: 'Switch to COD (certified)'), h.cod_no_check_order_path(order.id, customer_id: order.customer_id, return_path: return_path))
                        end
      end

      if cancelable?
        confirm_msg = 'Cancelling this order will mark it cancelled and void any payments. Press OK to continue.'
        if order.customer&.is_amazon_seller_central?
          confirm_msg = 'Amazon Seller Central FBM orders *MUST BE CANCELED MANUALLY ON SELLER CENTRAL*. We DO NOT support automatic Amazon Seller order cancellation via API. Cancelling this order will mark it cancelled and void any payments in Heatwave only. Press OK to continue.'
        end
        confirm_msg = h.prepurchased_label_void_confirm(order, confirm_msg)
        actions_list << h.link_to(h.fa_icon('ban', text: 'Cancel'), h.cancel_order_path(order, return_path: return_path),
                                  data: { turbo_method: :post, turbo_confirm: confirm_msg })
      end
    end

  end

  actions_list
end

#actual_shipping_costObject



331
332
333
# File 'app/presenters/order_presenter.rb', line 331

def actual_shipping_cost
  @actual_shipping_cost ||= order.calculate_actual_shipping_cost
end


8
9
10
11
12
13
14
15
16
17
18
19
20
# File 'app/presenters/order_presenter.rb', line 8

def breadcrumb
  if quote
    h.build_breadcrumb(quote)
  elsif opportunity
    h.build_breadcrumb(opportunity)
  elsif rma
    h.build_breadcrumb(rma)
  elsif contact
    h.build_breadcrumb(contact)
  else
    h.build_breadcrumb(customer)
  end
end

#estimated_shipping_costObject



341
342
343
# File 'app/presenters/order_presenter.rb', line 341

def estimated_shipping_cost
  order.shipping_cost
end

#exceeds_shipping_cost_threshold?Boolean

Returns:

  • (Boolean)


335
336
337
338
339
# File 'app/presenters/order_presenter.rb', line 335

def exceeds_shipping_cost_threshold?
  return false unless actual_shipping_cost && estimated_shipping_cost

  actual_shipping_cost > (0.75 * estimated_shipping_cost)
end

#fraud_alertObject



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
# File 'app/presenters/order_presenter.rb', line 40

def fraud_alert
  return unless pending_release_authorization? && potential_fraud?

  t1 = h.(:p, 'This order has been flagged as potentially fraudulent due to the following reasons:')
  t2 = h.(:ul) do
    potential_fraud_reasons.each do |reason|
      h.concat h.(:li, reason)
    end
  end
  if payments_with_fraud_report.empty?
    t3 = h.(:p, 'Order needs to be approved by an authorized rep')
  elsif payments_with_fraud_report.size == 1
    t3 = h.centered_row do
      h.concat h.(:div, h.link_to('Review fraud report for more information', h.fraud_report_payment_path(payments_with_fraud_report.first), class: 'btn btn-primary', style: 'margin-right:30px'))
      h.concat h.(:div, h.link_to('Order is not Fraudulent', h.approve_fraud_report_payment_path(payments_with_fraud_report.first), class: 'btn btn-success')) if h.user_has_role?('order_authorizer') || h.user_has_role?('accounting_rep')
    end

  else
    t3a = h.(:p, 'Review fraud reports for more information:')
    t3b = h.(:ul) do
      payments_with_fraud_report.each do |auth|
        h.concat h.(:li, h.link_to("Fraud report for payment #{auth.id}", h.fraud_report_payment_path(auth)))
      end
    end
    t3 = t3a + t3b
  end
  h.(:div, class: 'alert alert-danger', role: 'alert') do
    t1 + t2 + t3
  end
end

#general_alertsObject



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
114
115
116
117
118
119
120
121
122
123
124
125
# File 'app/presenters/order_presenter.rb', line 71

def general_alerts
  alerts = []

  if order.stop_for_pre_pack?
    res = order.need_to_pre_pack_reasons
    alerts << "Shipping estimate may be inaccurate. You may want to request estimated packaging for this order, it meets the criteria: #{res.join('. ')}"
  end

  alerts << 'Credit card payment on this order has expired and could not be automatically re-authorized. Please contact customer to take payment again.' if pending_payment? && payments.expired.exists?

  alerts << "Order has payments in a different currency than the order (#{currency}). Please void those payments and re-authorize." if payments.all_authorized.where.not(currency: currency).exists?

  if awaiting_deliveries? && deliveries.for_future_release.any?
    alerts << "Order is at warehouse but has a future release date of #{deliveries.for_future_release.pluck(:future_release_date).collect do |d|
      d.to_fs(:crm_default)
    end.join(' and ')}#{' (manual)' if manual_release_only?}#{' and stock is not reserved' if do_not_reserve_stock?}"
  end

  alerts << I18n.t('order.custom_order_required') if is_sales_order? && custom_order_agreement_required? && !uploads.in_category('custom_order_agreement').exists?

  alerts << 'Waiting for customer to pay PayPal invoice.' if pending_release_authorization? and payments.paypal_invoices.all_authorized.any? { |pp| !pp.captured? }

  alerts << 'One or more payments need to be approved by accounting before releasing this order.' if pending_release_authorization? and payments.any? { |pp| !pp.payment_approved? && (pp.authorization_review[:required] == true) }

  if (created? or awaiting_return? or pending_review?) and discount_adjustment_needed?
    alerts << 'Discounts could not be copied from the original order, possibly only part of a kit was returned. Adjustments may be needed to match the original sale price.'
  end

  if billing_address.present? && catalog.store&.country != billing_address.country && !is_store_transfer? && !billing_address.country.eu_country?
    alerts << "This is an international order. Billing address country is different than catalog store country (Billing address: #{billing_address.country.name} / Catalog: #{catalog.store&.country&.name})"
  end

  alerts << 'Do not release backorder without prior approval from rep' if hold_bo_release?
  # if line_items.services.with_positive_qty.any? && line_items.goods.with_positive_qty.any?
  #   alerts << "Cannot combine service items with goods in the same order. Please split this order."
  # end

  # Warn if Tech Order (TO) has no tracking email - customer won't receive shipment notifications
  if is_tech_order? && tracking_email.blank? && !shipped?
    alerts << 'No tracking email configured. The customer will not receive shipment notifications. ' \
              '<a href="#order-tracking-email" data-bs-toggle="collapse">Add a tracking email</a> before shipping.'
  end

  alerts += hold_order_reasons if in_cr_hold?

  return unless alerts.present?

  h.(:div, class: 'alert alert-danger', role: 'alert') do
    h.(:ul, class: "#{'list-unstyled mb-0' if alerts.size == 1}") do
      alerts.each do |n|
        h.concat h.(:li, n.html_safe, class: 'py-1')
      end
    end
  end
end

#general_noticesObject



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'app/presenters/order_presenter.rb', line 142

def general_notices
  notices = []

  notices << 'There is a SALE PRICE in effect for at least one of the line items. Please check the line item prices are correct' if order.is_edi_order? && order.line_items.any? { |li| li.catalog_item&.sale_price_in_effect? }

  if shipping_address.present? && catalog.store&.country != shipping_address.country && !is_store_transfer? && !shipping_address.country.eu_country?
    notices << "This is an international order. Shipping address country is different than catalog store country (Shipping address: #{shipping_address.country.name} / Catalog: #{catalog.store&.country&.name})"
  end

  return unless notices.present?

  h.(:div, class: 'alert alert-warning', role: 'alert') do
    h.(:ul, class: "#{'list-unstyled mb-0' if notices.size == 1}") do
      notices.each do |n|
        h.concat h.(:li, n.html_safe, class: 'py-1')
      end
    end
  end
end

#get_order_profit_labelObject



386
387
388
389
390
391
# File 'app/presenters/order_presenter.rb', line 386

def get_order_profit_label
  profit_label = +'Profit: '
  profit_label << h.colored_profit_status(order)
  profit_label << " (#{h.colored_profit(order)}, min: #{order.min_profit_markup} %)"
  profit_label.html_safe
end

#my_projects_referenceObject



34
35
36
37
38
# File 'app/presenters/order_presenter.rb', line 34

def my_projects_reference
  return if customer_reference.nil? || customer_reference.empty?

  "Customer Reference: #{customer_reference}"
end

#needs_attention_issues_textObject



393
394
395
396
397
# File 'app/presenters/order_presenter.rb', line 393

def needs_attention_issues_text
  res = nil
  res = "#{needs_attention_issues.join(', ')}!" if needs_attention_issues.any?
  res
end

#order_identifiersObject



368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
# File 'app/presenters/order_presenter.rb', line 368

def order_identifiers
  ids = []
  ids << h.employee_badge(order.primary_sales_rep, title: 'Primary Sales Rep') if order.primary_sales_rep
  ids << fa_icon('file-invoice-dollar', text: order_total)
  ids << fa_icon('tags', text: "Effective Discount: #{effective_discount} %".html_safe)
  if track_profit?
    if h.can?(:manage_profit_margins, order)
      profit_info = h.link_to(h.profit_margins_order_path(order), class: 'px-2 nav-link') do
        h.safe_join([fa_icon('chart-pie'), h.(:span, get_order_profit_label, class: 'copy-target')], ' ')
      end
      ids << profit_info
    else
      ids << (:span, fa_icon('chart-pie', text: "Profit Status: #{h.colored_profit_status(order)}".html_safe))
    end
  end
  ids
end

#order_totalObject



26
27
28
29
30
31
32
# File 'app/presenters/order_presenter.rb', line 26

def order_total
  if order_type == Order::CREDIT_ORDER
    h. :span, h.number_to_currency(total, unit: currency_symbol), class: 'return-order-total'
  else
    h. :span, h.number_to_currency(total, unit: currency_symbol)
  end
end

#reference_numberObject



22
23
24
# File 'app/presenters/order_presenter.rb', line 22

def reference_number
  order.reference_number.presence || "Order/Cart ID #{id}"
end

#shipping_cost_infoObject



345
346
347
348
# File 'app/presenters/order_presenter.rb', line 345

def shipping_cost_info
  style = 'color:red;font-weight:bold' if exceeds_shipping_cost_threshold?
  h.(:span, h.number_to_currency(actual_shipping_cost), style: style)
end

#shipping_warningsObject

Warnings that should be displayed but don't block order release



128
129
130
131
132
133
134
135
136
137
138
139
140
# File 'app/presenters/order_presenter.rb', line 128

def shipping_warnings
  warnings = shipping_date_warnings

  return unless warnings.present?

  h.(:div, class: 'alert alert-warning', role: 'alert') do
    h.(:ul, class: "#{'list-unstyled mb-0' if warnings.size == 1}") do
      warnings.each do |w|
        h.concat h.(:li, w.html_safe, class: 'py-1')
      end
    end
  end
end

#show_order_pre_pack_option(order) ⇒ Object



399
400
401
# File 'app/presenters/order_presenter.rb', line 399

def show_order_pre_pack_option(order)
  order.deliveries.any? && (order.shipments.any? { |s| !s.packed_or_pre_packed? } || (h.current_user&.has_role?('warehouse_rep') || h.current_user&.is_manager?))
end

#who_infoObject



350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
# File 'app/presenters/order_presenter.rb', line 350

def who_info
  info = []
  if order_rep = order.primary_sales_rep || order.customer.primary_sales_rep
    r = String.new("Rep: #{order_rep.full_name}")
    r << " x#{order_rep.pbx_extension}" if order_rep.pbx_extension
    info << r
  end
  if order_creator = order.creator
    r = String.new("Creator: #{order_creator.full_name}")
    if pbx_ext = order_creator.try(:pbx_extension)
      r << " ext: #{pbx_ext}"
    end
    info << r
  end
  info << "Created on: #{h.render_datetime(order.created_at)}" if order.created_at
  info.each_with_index.map { |n, idx| idx.positive? ? (:a, n) : n }
end