Class: DeliveriesController
- Inherits:
-
CrmController
- Object
- ActionController::Base
- ApplicationController
- CrmController
- DeliveriesController
- Includes:
- Controllers::RequireTurboFrame, Controllers::WarehouseStreamActions, Controllers::Workflowable
- Defined in:
- app/controllers/deliveries_controller.rb
Overview
Controller: deliveries.
Constant Summary collapse
- TAB_ACTIONS =
Tab fragments never render standalone — non-frame hits redirect to show ?tab=.
%i[tab_main tab_shipping tab_line_items tab_invoices tab_item_ledger tab_account_ledger tab_shipping_api_log tab_freight_events tab_tracking_events].freeze
- COMPLETE_PICKING_SUBMIT =
Complete picking submit.
'Save and complete picking'- COMPLETE_PRE_PACKING_SUBMIT =
Complete pre packing submit.
'Save and complete packaging estimate'- GENERATE_LABELS =
Generate labels.
'Generate Labels'- MANUAL_LABELS =
Manual labels.
'Manual Labels'- DELETE_ALL_SHIPMENTS =
Delete all shipments.
'Delete all shipments'- PRINT_CARTON_LABELS =
Print carton labels.
'Print carton labels'
Constants included from Controllers::WarehouseStreamActions
Controllers::WarehouseStreamActions::WAREHOUSE_TAB_CONTENT_FRAME
Constants included from Controllers::ReferenceFindable
Controllers::ReferenceFindable::ID_EMBEDDED_PATTERNS
Constants included from Controllers::AnalyticsEvents
Controllers::AnalyticsEvents::MAX_QUEUED_EVENTS, Controllers::AnalyticsEvents::SESSION_KEY
Constants included from Controllers::ErrorRendering
Controllers::ErrorRendering::NON_CONTENT_PATH_PREFIXES
Instance Method Summary collapse
-
#bol ⇒ void
Renders the Bill of Lading (HTML preview or PDF download).
-
#booking_summary ⇒ Object
LTL freight booking summary — the landing page after generating LTL labels.
-
#cancel_cod_check ⇒ void
Clears COD collection by check and recalculates shipping.
-
#cancel_cod_no_check ⇒ void
Clears COD collection without check and recalculates shipping.
-
#cancel_ltl_freight ⇒ void
Turns off LTL freight and re-rates the delivery.
-
#cancel_ltl_freight_guaranteed ⇒ void
Turns off guaranteed LTL freight (back to standard LTL) and re-rates.
-
#cancel_ltl_freight_prepack ⇒ void
Turns off LTL freight during pre-packing and re-rates the delivery.
-
#cancel_pickup ⇒ void
Cancels the scheduled carrier pickup for the delivery.
-
#cancel_saturday_delivery ⇒ void
Disables Saturday delivery and recalculates shipping.
-
#cancel_signature_confirmation ⇒ void
Disables signature confirmation and recalculates shipping.
-
#check_if_ships_freight_and_address_freight_ready ⇒ void
Redirects to the shipping-address form when the order ships freight but the address is missing freight-related fields.
-
#choose_ships_economy_carrier ⇒ void
Renders the economy-carrier chooser for a ships-economy delivery.
-
#ci ⇒ void
Renders the commercial invoice (HTML preview or PDF download).
-
#ci_legacy ⇒ void
Renders the legacy commercial invoice, appending any USMCA certificate PDFs to the PDF output.
-
#cod_check ⇒ void
Sets COD collection by check and recalculates shipping.
-
#cod_no_check ⇒ void
Sets COD collection without check and recalculates shipping.
-
#complete_asynch_print_bol ⇒ Object
Landing target after GetFreightquoteLoadNumber finishes (via job-page redirect).
-
#complete_asynch_print_speedee ⇒ Object
Landing target after SpeedeeLabelWorker finishes (via job-page redirect).
-
#complete_palletization ⇒ void
Saves pallet/container assignments and completes picking when pallet weights match shipment weights.
-
#complete_picked ⇒ void
Handles the picking form submit: delete-all-shipments, save + optional palletization detour, or completion of picking.
-
#complete_ship_label ⇒ void
Handles the ship-label form submit: generate carrier labels (sync or via async workers for Freightquote/Spee-Dee), manual labels, carton-label printing, or a plain delivery save.
-
#create ⇒ Object
POST /deliveries POST /deliveries.xml.
-
#edit ⇒ Object
GET /deliveries/1/edit.
-
#edit_release_date ⇒ void
Renders the release-date edit form.
-
#edit_shipment_contents ⇒ void
Renders the shipment-contents editor.
-
#edit_tracking ⇒ void
Renders the tracking-number edit form.
-
#export_shipments_contents_to_csv ⇒ void
Downloads a CSV of the delivery's shipment containers and their contents.
-
#finish_void_shipments ⇒ void
Voids the delivery's shipments (recording the operator's reason) and returns the delivery to pending ship-label.
-
#hold ⇒ void
(also: #cancel_picking)
Puts the delivery's order on CR hold, optionally routing to stock reservation when
reserve_stock=1. -
#index ⇒ Object
These are actions for deliveries PAST the quoting stage, ie at_warehouse or beyond.
-
#ltl_freight ⇒ void
Switches the delivery to LTL freight and re-rates it.
-
#ltl_freight_guaranteed ⇒ void
Switches the delivery to guaranteed LTL freight and re-rates it.
-
#ltl_freight_prepack ⇒ void
Switches the delivery to LTL freight during pre-packing and re-rates it.
-
#multiple_origin ⇒ void
Switches the order/quote to multiple-origin shipping and recalculates.
-
#new ⇒ Object
GET /deliveries/new GET /deliveries/new.xml.
-
#palletization ⇒ void
Renders the pallet/container assignment confirmation screen.
-
#pending_confirm ⇒ void
Moves a shipped delivery to pending-confirm state.
-
#pick_slip ⇒ void
Streams the packing-slip PDF for the delivery (
?split_kits=1splits kits). -
#picked ⇒ void
Renders the picking/packing screen; FBA-locked deliveries skip straight to pending ship-label.
-
#print_booking_documents ⇒ Object
Pipe one booking document (bol | ci | package) to the selected print profile, falling back to browser download when no profile is chosen.
-
#print_pick_slip ⇒ Object
GET /customers/1/orders/1/print_pick_slip.
-
#print_serial_numbers ⇒ void
Generates the serial-numbers PDF for the delivery and redirects to it.
-
#purchase_marketplace_label ⇒ Object
Eager purchase of marketplace labels (Walmart, Amazon, etc.) before warehouse picks the order This allows reporting tracking to marketplaces earlier.
-
#recalculate_shipping ⇒ void
Re-retrieves shipping costs for this delivery, persisting any submitted ship-by/deliver-by dates (non-marketplace orders only) and honoring an optional
rate_ship_dateoverride. -
#recalculate_shipping_all ⇒ void
Re-retrieves shipping costs for all deliveries of the order/quote.
-
#release ⇒ void
Releases the delivery from a scheduled future release.
-
#request_estimated_packaging ⇒ void
Moves the delivery (or its quote) into the pre-pack / estimated-packaging request flow.
-
#retry_asynch_carrier_confirm ⇒ void
Re-enqueues the asynchronous Freightquote load-number confirmation for a delivery still pending carrier confirm.
-
#saturday_delivery ⇒ void
Enables Saturday delivery and recalculates shipping.
-
#selected_shipping_account_number_id_from_params ⇒ String?
Extract the submitted shipping_account_number_id for the shipping_cost row identified by params[:shipping_cost_id] out of the nested deliveries/shipping_costs attributes.
-
#serial_numbers ⇒ void
Streams the serial-number label PDF for the delivery.
-
#ship_label ⇒ void
Renders the ship-label screen.
-
#shipped ⇒ void
Marks the delivery as shipped.
-
#show ⇒ Object
GET /deliveries/1 GET /deliveries/1.xml.
-
#show_shipment_content ⇒ void
Renders the read-only shipment-contents view.
-
#signature_confirmation ⇒ void
Enables signature confirmation and recalculates shipping.
-
#single_origin ⇒ void
Switches the order/quote to single-origin shipping and recalculates.
-
#switch_ships_economy_carrier ⇒ void
Saves the chosen economy carrier and applies the matching shipping rate.
-
#tab_account_ledger ⇒ void
Renders the account-ledger tab fragment for a delivery.
-
#tab_freight_events ⇒ void
Renders the freight-events tab fragment for a delivery.
-
#tab_invoices ⇒ void
Renders the invoices tab fragment for a delivery.
-
#tab_item_ledger ⇒ void
Renders the item-ledger tab fragment for a delivery.
-
#tab_line_items ⇒ void
Renders the line-items tab fragment for a delivery.
-
#tab_main ⇒ Object
Tab actions for turbo-tabs lazy loading.
-
#tab_shipping ⇒ void
Renders the shipping tab fragment for a delivery.
-
#tab_shipping_api_log ⇒ void
Renders the shipping API log tab fragment for a delivery.
-
#tab_tracking_events ⇒ void
Renders the tracking-events tab fragment for a delivery.
-
#trigger_invoiced ⇒ void
Triggers invoice creation for a shipped delivery.
-
#undismiss_problematic ⇒ Object
Reverses warehouse "Dismiss" (Crm::WarehousesController#dismiss_problematic_shipment) for every parcel on the delivery: clears the dismissal stamps so the ProblematicDeliverySweep flags, alerts, and badges them again.
-
#update ⇒ Object
PUT /deliveries/1 PUT /deliveries/1.xml.
-
#update_release_date ⇒ Object
TODO.
-
#update_shipping_cost ⇒ void
Applies the shipping-cost selection submitted from the rate screen.
-
#update_shipping_cost_account_number ⇒ void
Applies a shipping-account-number (SAN) change for a shipping cost, extracting the nested value from the form payload.
-
#update_shipping_cost_data(force_shipping_account_number = false, shipping_account_number_id = nil) ⇒ Boolean
Selects the shipping cost identified by
params[:shipping_cost_id]on the delivery, optionally updating its shipping account number, viaShipping::UpdateShippingMethod. -
#update_tracking ⇒ void
Saves tracking changes: a master tracking number applied to all completed shipments atomically, or a regular delivery update (sending the commercial invoice when an LTL PRO number arrives after invoicing).
-
#void_shipments ⇒ void
Renders the void-shipments confirmation form.
Methods included from Controllers::WarehouseStreamActions
Methods included from FileDownloadPresenter
Methods included from Controllers::RequireTurboFrame
require_in_pane_tab_frames, require_turbo_frame
Methods included from Controllers::Workflowable
#render_workflow_error_stream, #render_workflow_success_stream, #workflow_action, #workflow_action_complete
Methods inherited from CrmController
#access_denied, #context_id, #context_object, #crm_home_path, #current_ability, #default_url_options, #download_temp, #get_tempfile_path_for_download, #init_status_job_collector, #initialize_crm_lazy_chunks, #persist_enqueued_status_jobs, #record_not_found, #redirect_to_job_or_fallback, #render_edit_action, #set_context, #set_download_path, #stash_file_for_temp_download, #sync_admin_presence_cookie, #touch_employee_last_seen
Methods inherited from ApplicationController
#account_impersonated?, #add_to_flash, #after_sign_in_path_for, #bypass_forgery_protection?, #chat_enabled?, #cloudflare_cleared?, #default_catalog, #default_url_options, #enable_turbo_frames, #find_publication, #fix_invalid_accept_header, #init_js_utils, #is_globals_call?, #layout_by_resource, #locale_store, #redirect_to, #require_employee_for_crm, #set_base_host, #set_real_ip, #set_report_errors_for, #should_render_layout?, #skip_layout_for_turbo_frame?, #stamp_impersonation_context, #tab_frame_breakout_request?, #warmlyyours_canada_ip?, #warmlyyours_ip?, #y
Methods included from Controllers::ReturnPathHandling
#check_for_return_path, #redirect_to_return_path_or_default
Methods included from Controllers::AnalyticsEvents
#consume_queued_analytics_events, #registration_lead_type, #track_event
Methods included from Controllers::DeviceDetection
Methods included from Controllers::SubdomainDetection
#is_crm_request?, #is_www_request?, #json_request?
Methods included from Controllers::TurboSafeRedirect
Methods included from Controllers::TrackingDetection
#bot_request?, #gdpr_country?, #gdpr_country_data, #prevent_bots, #set_tracking_cookie, #track_visitor?
Methods included from Controllers::AcceleratedFileSending
#send_file_accelerated, #send_upload_accelerated
Methods included from Controllers::ErrorRendering
#excp_string, #mail_to_for_error_reporting, #render_400, #render_404, #render_406, #render_410, #render_500, #render_invalid_authenticity_token, #render_ip_spoof_error, #render_unpermitted_parameters, #safe_referer_or_fallback
Methods included from Controllers::TurnstileVerification
#load_turnstile_script_tag, #turnstile_lazy_widget, #turnstile_script_tag, #turnstile_widget, #validate_turnstile!
Methods included from Controllers::CloudflareCaching
edge_cached, #edge_cached_action?, #reset_cloudflare_cache, #set_cloudflare_cache, #skip_edge_cache!, #skip_session
Methods included from Controllers::Webpackable
#preload_webpack_fonts, #webpack_css_include, #webpack_css_url, #webpack_js_include, #wpd_is_running?
Methods included from Controllers::Localizable
#cloudflare_country_locale, #determine_request_locale, #geocoder_locale, #guest_user_locale_check, #locale_optional_www_auth_path?, #param_locale, #set_locale, #set_request_locale, #skip_localization?, #warmlyyours_ip_locale
Methods included from Controllers::Authenticable
#access_denied, #authenticate_account, #authenticate_account!, #authenticate_account_from_login_token!, #check_is_a_manager, #check_is_a_sales_manager, #check_is_an_admin, #check_is_an_employee, #check_party, #clear_mismatched_guest_user, #create_guest_user, #credentials?, #current_or_guest_user, #current_or_guest_user_id_read_only, #current_user, #devise_mapping, #fully_logged_in?, #generate_bot_id, #guest_user, #identifiable?, #init_current_user, #initialize_guest, #load_context_user, #logging_in, #resource, #resource_name, #restrict_access_for_non_employees, #scrubbed_request_path, #user_object, #warn_on_session_guest_id_leak
Methods included from UrlsHelper
#catalog_breadcrumb_links, #catalog_link, #catalog_link_for_product_line, #catalog_link_for_sku, #cms_link, #delocalized_path, #path_to_sales_product_sku, #path_to_sales_product_sku_for_product_line, #path_to_sales_product_sku_for_product_line_slug, #product_line_from_catalog_link, #protocol_neutral_url, #sanitize_external_url, #valid_external_url?
Instance Method Details
#bol ⇒ void
This method returns an undefined value.
Renders the Bill of Lading (HTML preview or PDF download).
1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 |
# File 'app/controllers/deliveries_controller.rb', line 1036 def bol @delivery = Delivery.find(params[:id]) respond_to do |format| format.html do render layout: 'pdf/bol', locals: { delivery: @delivery } end format.pdf do result = Shipping::BolGenerator.new.process(@delivery) send_data result.pdf, filename: result.file_name, type: 'application/pdf', disposition: 'inline' end end end |
#booking_summary ⇒ Object
LTL freight booking summary — the landing page after generating LTL labels.
Presents the document package (BOL / commercial invoice / full package) with
download + print-via-profile, and the pickup status: manual instructions
(carrier QuickPickup) or the automated confirmation.
764 765 766 767 768 769 |
# File 'app/controllers/deliveries_controller.rb', line 764 def booking_summary @documents = booking_documents @pickup = booking_pickup_status @print_profiles = PrintProfile.shipping_label.online.map { |pp| [pp.to_s, pp.id] } @default_print_profile_id = current_user.default_printer_profile(:shipping_label)&.id end |
#cancel_cod_check ⇒ void
This method returns an undefined value.
Clears COD collection by check and recalculates shipping.
478 479 480 481 482 483 484 |
# File 'app/controllers/deliveries_controller.rb', line 478 def cancel_cod_check @ship_quotable.cod_collection_type = nil @ship_quotable.need_to_recalculate_shipping @ship_quotable.save! err_msg = MessagingLog.(@delivery.messaging_logs) redirect_to polymorphic_path(@ship_quotable, action: :shipping, shipping_updated: true), flash: { error: err_msg } end |
#cancel_cod_no_check ⇒ void
This method returns an undefined value.
Clears COD collection without check and recalculates shipping.
571 572 573 574 575 576 577 |
# File 'app/controllers/deliveries_controller.rb', line 571 def cancel_cod_no_check @ship_quotable.cod_collection_type = nil @ship_quotable.need_to_recalculate_shipping @ship_quotable.save! err_msg = MessagingLog.(@delivery.messaging_logs) redirect_to polymorphic_path(@ship_quotable, action: :shipping, shipping_updated: true), flash: { error: err_msg } end |
#cancel_ltl_freight ⇒ void
This method returns an undefined value.
Turns off LTL freight and re-rates the delivery.
400 401 402 403 404 405 406 407 408 409 |
# File 'app/controllers/deliveries_controller.rb', line 400 def cancel_ltl_freight @delivery.ltl_freight = false res = @delivery.retrieve_shipping_costs @ship_quotable.do_not_detect_shipping = true @delivery.save @ship_quotable.save err_msg = nil err_msg = res[:message] unless res[:code] == :ok redirect_to polymorphic_path(@ship_quotable, action: :shipping, shipping_updated: true), flash: { error: err_msg } end |
#cancel_ltl_freight_guaranteed ⇒ void
This method returns an undefined value.
Turns off guaranteed LTL freight (back to standard LTL) and re-rates.
454 455 456 457 458 459 460 461 462 463 464 |
# File 'app/controllers/deliveries_controller.rb', line 454 def cancel_ltl_freight_guaranteed @delivery.ltl_freight = true @delivery.ltl_freight_guaranteed = false res = @delivery.retrieve_shipping_costs @ship_quotable.do_not_detect_shipping = true @delivery.save @ship_quotable.save err_msg = nil err_msg = res[:message] unless res[:code] == :ok redirect_to polymorphic_path(@ship_quotable, action: :shipping, shipping_updated: true), flash: { error: err_msg } end |
#cancel_ltl_freight_prepack ⇒ void
This method returns an undefined value.
Turns off LTL freight during pre-packing and re-rates the delivery.
427 428 429 430 431 432 433 434 435 436 |
# File 'app/controllers/deliveries_controller.rb', line 427 def cancel_ltl_freight_prepack @delivery.ltl_freight = false res = @delivery.retrieve_shipping_costs @ship_quotable.do_not_detect_shipping = true @delivery.save @ship_quotable.save err_msg = nil err_msg = res[:message] unless res[:code] == :ok redirect_to picked_delivery_path(@delivery, return_path: @return_path), flash: { error: err_msg } end |
#cancel_pickup ⇒ void
This method returns an undefined value.
Cancels the scheduled carrier pickup for the delivery.
751 752 753 754 |
# File 'app/controllers/deliveries_controller.rb', line 751 def cancel_pickup @delivery.cancel_pickup redirect_to_return_path_or_default delivery_path(@delivery) end |
#cancel_saturday_delivery ⇒ void
This method returns an undefined value.
Disables Saturday delivery and recalculates shipping.
356 357 358 359 360 361 362 |
# File 'app/controllers/deliveries_controller.rb', line 356 def cancel_saturday_delivery @ship_quotable.saturday_delivery = false @ship_quotable.need_to_recalculate_shipping @ship_quotable.save! err_msg = MessagingLog.(@delivery.messaging_logs) redirect_to polymorphic_path(@ship_quotable, action: :shipping, shipping_updated: true), flash: { error: err_msg } end |
#cancel_signature_confirmation ⇒ void
This method returns an undefined value.
Disables signature confirmation and recalculates shipping.
376 377 378 379 380 381 382 |
# File 'app/controllers/deliveries_controller.rb', line 376 def cancel_signature_confirmation @ship_quotable.signature_confirmation = false @ship_quotable.need_to_recalculate_shipping @ship_quotable.save! err_msg = MessagingLog.(@delivery.messaging_logs) redirect_to polymorphic_path(@ship_quotable, action: :shipping, shipping_updated: true), flash: { error: err_msg } end |
#check_if_ships_freight_and_address_freight_ready ⇒ void
This method returns an undefined value.
Redirects to the shipping-address form when the order ships freight but the
address is missing freight-related fields.
582 583 584 585 586 587 |
# File 'app/controllers/deliveries_controller.rb', line 582 def check_if_ships_freight_and_address_freight_ready return unless @ship_quotable.ships_freight_but_address_not_freight_ready? || (@ship_quotable.is_override? && @ship_quotable.should_ship_freight_but_address_not_freight_ready?) redirect_to edit_address_path(@ship_quotable.shipping_address, ships_freight: 'true', return_path: polymorphic_path(@ship_quotable, action: :shipping)), flash: { error: "Please complete selecting freight related fields on the shipping address, so we can calculate freight on this #{@ship_quotable.class.to_s.downcase}." } end |
#choose_ships_economy_carrier ⇒ void
This method returns an undefined value.
Renders the economy-carrier chooser for a ships-economy delivery.
1125 |
# File 'app/controllers/deliveries_controller.rb', line 1125 def choose_ships_economy_carrier; end |
#ci ⇒ void
This method returns an undefined value.
Renders the commercial invoice (HTML preview or PDF download).
1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 |
# File 'app/controllers/deliveries_controller.rb', line 1057 def ci @delivery = Delivery.find(params[:id]) respond_to do |format| format.html do render layout: 'pdf/ci', locals: { delivery: @delivery } end format.pdf do pdf_data = Pdf::Document::CommercialInvoice.new(@delivery).call.pdf send_data pdf_data, filename: "#{@delivery.reference_number}_CI.pdf", type: 'application/pdf', disposition: 'inline' end end end |
#ci_legacy ⇒ void
This method returns an undefined value.
Renders the legacy commercial invoice, appending any USMCA certificate
PDFs to the PDF output.
1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 |
# File 'app/controllers/deliveries_controller.rb', line 1079 def ci_legacy @delivery = Delivery.find(params[:id]) respond_to do |format| format.html do render layout: 'pdf/ci', locals: { delivery: @delivery } end format.pdf do pdf_data = Pdf::Document::CommercialInvoice.new(@delivery).call.pdf usmca_cert_uploads = Upload.where(category: 'usmca_certificate').joins(items: :line_items).merge(@delivery.line_items) if usmca_cert_uploads.present? combined = PdfCombinator.new combined << pdf_data usmca_cert_uploads.each do |upload| combined << upload..data if upload.&.data.present? rescue StandardError nil end pdf_data = combined.to_pdf end send_data pdf_data, filename: "#{@delivery.reference_number}_CI.pdf", type: 'application/pdf', disposition: 'inline' end end end |
#cod_check ⇒ void
This method returns an undefined value.
Sets COD collection by check and recalculates shipping.
468 469 470 471 472 473 474 |
# File 'app/controllers/deliveries_controller.rb', line 468 def cod_check @ship_quotable.cod_collection_type = 'check' @ship_quotable.need_to_recalculate_shipping @ship_quotable.save! err_msg = MessagingLog.(@delivery.messaging_logs) redirect_to polymorphic_path(@ship_quotable, action: :shipping, shipping_updated: true, shipping_update_type: 'cod_check'), flash: { error: err_msg } end |
#cod_no_check ⇒ void
This method returns an undefined value.
Sets COD collection without check and recalculates shipping.
561 562 563 564 565 566 567 |
# File 'app/controllers/deliveries_controller.rb', line 561 def cod_no_check @ship_quotable.cod_collection_type = 'no_check' @ship_quotable.need_to_recalculate_shipping @ship_quotable.save! err_msg = MessagingLog.(@delivery.messaging_logs) redirect_to polymorphic_path(@ship_quotable, action: :shipping, shipping_updated: true, shipping_update_type: 'cod_no_check'), flash: { error: err_msg } end |
#complete_asynch_print_bol ⇒ Object
Landing target after GetFreightquoteLoadNumber finishes (via job-page
redirect). The worker already rendered the BOL / commercial invoice /
combined-labels PDFs and sent them to the printer, so this is navigation
plus the browser-download fallback.
931 932 933 |
# File 'app/controllers/deliveries_controller.rb', line 931 def complete_asynch_print_bol replay_download_fallback(tab: 'pending_ship_labels') end |
#complete_asynch_print_speedee ⇒ Object
Landing target after SpeedeeLabelWorker finishes (via job-page redirect).
The worker already rendered the per-package + combined label PDFs, fired
ship_labeled and sent the labels to the printer, so this lands the operator
on the manifest-completion tab (Spee-Dee still needs the daily portal
manifest).
940 941 942 |
# File 'app/controllers/deliveries_controller.rb', line 940 def complete_asynch_print_speedee replay_download_fallback(tab: 'pending_manifest_completion') end |
#complete_palletization ⇒ void
This method returns an undefined value.
Saves pallet/container assignments and completes picking when pallet
weights match shipment weights.
58 59 60 61 62 63 64 65 |
# File 'app/controllers/deliveries_controller.rb', line 58 def complete_palletization if @delivery.update(params[:delivery] || {}) & @delivery.pallet_weight_matching complete_picked_action else flash.now[:error] = @delivery.errors_to_s.presence || 'Pallet weights do not match shipment weights.' render :palletization, status: :unprocessable_content end end |
#complete_picked ⇒ void
This method returns an undefined value.
Handles the picking form submit: delete-all-shipments, save + optional
palletization detour, or completion of picking.
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'app/controllers/deliveries_controller.rb', line 70 def complete_picked if params[:commit] == DELETE_ALL_SHIPMENTS @delivery.shipments.destroy_all flash[:info] = 'All shipments were deleted' render_picked_action elsif @delivery.update(params[:delivery] || {}) if @delivery.shipments.pallets.present? && (@delivery.shipments.cartons.present? || @delivery.shipments.crates.present?) redirect_to palletization_delivery_path(@delivery) else complete_picked_action end else render_picked_action end end |
#complete_ship_label ⇒ void
This method returns an undefined value.
Handles the ship-label form submit: generate carrier labels (sync or via
async workers for Freightquote/Spee-Dee), manual labels, carton-label
printing, or a plain delivery save.
788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 |
# File 'app/controllers/deliveries_controller.rb', line 788 def complete_ship_label # `has_many :shipments` declares an order(:created_at), which find_each # silently dropped on Rails 7 and warns about on Rails 8 (it paginates by # id internally). The iteration here doesn't care about ordering — make # that explicit with reorder(nil) to suppress the warning. @delivery.shipments.where(state: %w[packed]).reorder(nil).find_each(&:ready_for_label) @shipments = @delivery.shipments.awaiting_label print_uploads = [] if params[:commit] == GENERATE_LABELS # Push the delivery carrier down @shipments.each { |s| s.update(carrier: @delivery.carrier, is_manual: false) } result = @delivery.generate_labels if result[:status_code] != :ok @delivery.errors.add(:base, result[:status_message] || 'Unable to print ship labels, please contact a member of the IT team for assistance') render :ship_label, status: :unprocessable_content elsif result[:status_code] == :ok if @delivery.carrier == 'Freightquote' && @delivery.pending_carrier_confirm? # The worker renders the documents AND prints them (see # Workers::LabelPrinting) — carry the operator's print selection in the # job args so it survives however long the job waits in the queue. The # session stash is only for the browser-download fallback replayed by # complete_asynch_print_bol. stash_asynch_print_intent job_id = GetFreightquoteLoadNumber.perform_async({ delivery_id: @delivery.id, current_user_id: @context_user.id, print_intent: params_print_intent }.deep_stringify_keys) if job_id redirect_to job_path(job_id) else @delivery.errors.add(:base, result[:status_message] || ('FreightQuote load number monitor')) render :ship_label, status: :unprocessable_content end elsif result[:speedee_async] # Spee-Dee order is created; barcodes finalize asynchronously — poll + # render + print in SpeedeeLabelWorker, land the operator on the job # page, then redirect to complete_asynch_print_speedee. Mirrors # Freightquote. params[:print] — the operator's printer profile, # carton-label intent, and upload ids — belongs to THIS request only, # so it rides along in the job args (the worker prints) and in the # session (the landing page's download fallback). stash_asynch_print_intent job_id = SpeedeeLabelWorker.perform_async({ delivery_id: @delivery.id, current_user_id: @context_user.id, print_intent: params_print_intent }.deep_stringify_keys) if job_id redirect_to job_path(job_id) else @delivery.errors.add(:base, result[:status_message] || ('Spee-Dee label finalization')) render :ship_label, status: :unprocessable_content end else label_pdf = @delivery.all_labels_pdf print_uploads << label_pdf if label_pdf && !@order.is_rma_return? handle_print_uploads(@shipments, print_uploads) set_pickup_confirmation_flash(@delivery) Mailer.manual_pickup_required_email(@delivery).deliver_later if @delivery.requires_manual_pickup? if @delivery.ships_ltl_freight? # LTL freight: land the operator on the booking summary, which presents # the document package (BOL / commercial invoice) plus pickup # instructions (manual) or the confirmation (automated). redirect_to booking_summary_delivery_path(@delivery) else if @delivery.requires_manual_pickup? contact = @delivery.manual_pickup_contact flash[:error] = "<strong>Manual Pickup Required</strong> — " \ "<strong>#{ERB::Util.html_escape(contact[:name])}</strong> " \ "(#{ERB::Util.html_escape(contact[:location])}) does not support automated pickup. " \ "Warehouse staff <strong>MUST</strong> arrange pickup: " \ "<a href=\"tel:#{ERB::Util.html_escape(contact[:phone].gsub(/[^\d+]/, ''))}\">#{ERB::Util.html_escape(contact[:phone])}</a> " \ "| <a href=\"mailto:#{ERB::Util.html_escape(contact[:email])}\">#{ERB::Util.html_escape(contact[:email])}</a> " \ "| <a href=\"#{ERB::Util.html_escape(contact[:url])}\" target=\"_blank\" rel=\"noopener\"><strong>Schedule Quick Pickup</strong></a>" end redirect_to_return_path_or_default warehouse_path(@order.store, tab: 'pending_ship_labels') end end end elsif params[:commit] == MANUAL_LABELS && params[:delivery].present? override_carrier = params[:delivery].delete(:override_carrier) @delivery.attributes = params[:delivery] @delivery.shipments.select(&:awaiting_label?).each do |shp| shp.carrier = override_carrier if (shp.carrier.blank? || shp.carrier.to_s.downcase.include?('override')) && override_carrier.present? shp.tracking_number ||= @delivery.master_tracking_number shp.is_manual = true end if @delivery.save && @delivery.shipments.awaiting_label.all?(&:manually_complete) @delivery.reload.ship_labeled! @shipments = @delivery.shipments.manually_complete handle_print_uploads(@shipments, print_uploads) redirect_to_return_path_or_default delivery_path(@delivery, tab: 'shipping') else # `validates_associated :shipments` only reports "Shipments is invalid", # so lift the shipments' own messages up — a rejected tracking number # has to tell the operator which number and why. @delivery.shipments.select(&:awaiting_label?).flat_map { |shp| shp.errors. }.uniq.each do |msg| @delivery.errors.add(:base, msg) end @delivery.errors.add(:base, 'Cannot complete manual shipment. A carrier and tracking number, PRO number, or BOL number must be specified') render :ship_label, status: :unprocessable_content end elsif params[:commit] == PRINT_CARTON_LABELS flash[:info] = 'Carton Labels sent to printer' # The "Print carton labels" submit means the user explicitly wants carton # (SSCC) labels. The `print[:container_label]` checkbox in handle_print_uploads # is only rendered when the store has a current_shipping_label_print_profile # (see ship_label.html.erb), so for users without one the button silently did # nothing. Force the flag here -- the click itself is the intent. handle_print_uploads(@shipments, generate_carton_labels: true) redirect_to_return_path_or_default ship_label_delivery_path(@delivery) elsif @delivery.update(params[:delivery]) flash[:info] = "Delivery #{view_context.link_to(@delivery.reference_number, delivery_path(@delivery))} saved" redirect_to_return_path_or_default warehouse_path(@order.store, tab: 'pending_ship_labels') else flash.now[:error] = @delivery.errors_to_s.presence || 'Could not save delivery.' render :ship_label, status: :unprocessable_content end end |
#create ⇒ Object
POST /deliveries
POST /deliveries.xml
675 676 677 678 679 680 681 682 683 684 685 686 687 |
# File 'app/controllers/deliveries_controller.rb', line 675 def create @delivery = Delivery.new(params[:delivery]) respond_to do |format| if @delivery.save format.html { redirect_to(@delivery, notice: 'Delivery was successfully created.') } format.xml { render xml: @delivery, status: :created, location: @delivery } else format.html { render action: 'new', status: :unprocessable_content } format.xml { render xml: @delivery.errors, status: :unprocessable_content } end end end |
#edit ⇒ Object
GET /deliveries/1/edit
640 641 642 |
# File 'app/controllers/deliveries_controller.rb', line 640 def edit @delivery = Delivery.find(params[:id]) end |
#edit_release_date ⇒ void
This method returns an undefined value.
Renders the release-date edit form.
646 |
# File 'app/controllers/deliveries_controller.rb', line 646 def edit_release_date; end |
#edit_shipment_contents ⇒ void
This method returns an undefined value.
Renders the shipment-contents editor.
1030 1031 1032 |
# File 'app/controllers/deliveries_controller.rb', line 1030 def edit_shipment_contents @delivery = Delivery.find(params[:id]) end |
#edit_tracking ⇒ void
This method returns an undefined value.
Renders the tracking-number edit form.
88 |
# File 'app/controllers/deliveries_controller.rb', line 88 def edit_tracking; end |
#export_shipments_contents_to_csv ⇒ void
This method returns an undefined value.
Downloads a CSV of the delivery's shipment containers and their contents.
1141 1142 1143 1144 1145 1146 1147 1148 1149 1150 1151 1152 1153 1154 1155 1156 |
# File 'app/controllers/deliveries_controller.rb', line 1141 def export_shipments_contents_to_csv csv_string = CSV.generate do |csv| # header row csv << ['Container Code', 'Weight', 'Dimensions', 'Contents'] # data rows @delivery.shipments.each do |s| csv << [s.container_code.to_s, "#{s.weight.ceil} lbs", s.dimensions_text(display_units: true), s.shipment_contents.map { |sc| "#{sc.quantity} x #{sc.line_item.sku}" }.join(', ')] end end # send it to the browsah send_data csv_string, type: 'text/csv; charset=iso-8859-1; header=present', disposition: "attachment; filename=#{@delivery.name}.csv" end |
#finish_void_shipments ⇒ void
This method returns an undefined value.
Voids the delivery's shipments (recording the operator's reason) and
returns the delivery to pending ship-label.
951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 |
# File 'app/controllers/deliveries_controller.rb', line 951 def finish_void_shipments note = params.dig(:note, :content).presence || 'none given' Delivery.transaction do @delivery.quick_note("VOIDing shipments, reason: #{note}") result = @delivery.void_shipments if result[:status_code] == :error flash.now[:error] = "#{view_context.link_to @delivery.name, delivery_path(@delivery)} #{result[:status_message]}" render :void_shipments, status: :unprocessable_content else flash[:info] = "#{view_context.link_to @delivery.name, delivery_path(@delivery)} #{result[:status_message]}" # Move delivery back tp pending ship label @delivery.cancel_shipments! if @delivery.can_cancel_shipments? redirect_to_return_path_or_default warehouse_path(@order.store) end end end |
#hold ⇒ void Also known as: cancel_picking
This method returns an undefined value.
Puts the delivery's order on CR hold, optionally routing to stock
reservation when reserve_stock=1.
727 728 729 730 731 732 733 734 735 736 737 738 |
# File 'app/controllers/deliveries_controller.rb', line 727 def hold @order.cr_hold if @order.can_cr_hold?(current_user) unless @order.in_cr_hold? # here we use select form to pass current_user to each delivery's cancelable? method flash[:error] = "Delivery/order could not be held: some deliveries in the order are not cancelable: #{@order.deliveries.active.reject { |d| d.cancelable?(current_user) }.map { |d| "#{d.name(true)}: #{d.state}" }.inspect}" end if @order.in_cr_hold? && (params[:reserve_stock] == '1') redirect_to pick_lines_inventory_commits_path(resource_type: 'Order', resource_id: @order.id), notice: 'Order is on hold, please select which items you would like to reserve and click Save' else redirect_to_return_path_or_default order_path(@order) end end |
#index ⇒ Object
These are actions for deliveries PAST the quoting stage, ie at_warehouse or beyond
590 591 592 593 594 |
# File 'app/controllers/deliveries_controller.rb', line 590 def index @q = Delivery.ransack(params[:q]) @q.sorts = 'created_at DESC' if @q.sorts.blank? @pagy, @deliveries = pagy(:countish, @q.result) end |
#ltl_freight ⇒ void
This method returns an undefined value.
Switches the delivery to LTL freight and re-rates it.
386 387 388 389 390 391 392 393 394 395 396 |
# File 'app/controllers/deliveries_controller.rb', line 386 def ltl_freight @delivery.ltl_freight = true @delivery.ltl_freight_guaranteed = false res = @delivery.retrieve_shipping_costs @ship_quotable.do_not_detect_shipping = true @delivery.save @ship_quotable.save err_msg = nil err_msg = res[:message] unless res[:code] == :ok redirect_to polymorphic_path(@ship_quotable, action: :shipping, shipping_updated: true, shipping_update_type: 'ltl_freight'), flash: { error: err_msg } end |
#ltl_freight_guaranteed ⇒ void
This method returns an undefined value.
Switches the delivery to guaranteed LTL freight and re-rates it.
440 441 442 443 444 445 446 447 448 449 450 |
# File 'app/controllers/deliveries_controller.rb', line 440 def ltl_freight_guaranteed @delivery.ltl_freight = false @delivery.ltl_freight_guaranteed = true res = @delivery.retrieve_shipping_costs @ship_quotable.do_not_detect_shipping = true @delivery.save @ship_quotable.save err_msg = nil err_msg = res[:message] unless res[:code] == :ok redirect_to polymorphic_path(@ship_quotable, action: :shipping, shipping_updated: true, shipping_update_type: 'ltl_freight_guaranteed'), flash: { error: err_msg } end |
#ltl_freight_prepack ⇒ void
This method returns an undefined value.
Switches the delivery to LTL freight during pre-packing and re-rates it.
413 414 415 416 417 418 419 420 421 422 423 |
# File 'app/controllers/deliveries_controller.rb', line 413 def ltl_freight_prepack @delivery.ltl_freight = true @delivery.ltl_freight_guaranteed = false res = @delivery.retrieve_shipping_costs @ship_quotable.do_not_detect_shipping = true @delivery.save @ship_quotable.save err_msg = nil err_msg = res[:message] unless res[:code] == :ok redirect_to picked_delivery_path(@delivery, return_path: @return_path), flash: { error: err_msg } end |
#multiple_origin ⇒ void
This method returns an undefined value.
Switches the order/quote to multiple-origin shipping and recalculates.
218 219 220 221 222 |
# File 'app/controllers/deliveries_controller.rb', line 218 def multiple_origin @ship_quotable.need_to_recalculate_shipping @ship_quotable.update(ltl_freight: false, ltl_freight_guaranteed: false, single_origin: false) redirect_to polymorphic_path(@ship_quotable, action: :shipping, shipping_updated: true) end |
#new ⇒ Object
GET /deliveries/new
GET /deliveries/new.xml
630 631 632 633 634 635 636 637 |
# File 'app/controllers/deliveries_controller.rb', line 630 def new @delivery = Delivery.new respond_to do |format| format.html # new.html.erb format.xml { render xml: @delivery } end end |
#palletization ⇒ void
This method returns an undefined value.
Renders the pallet/container assignment confirmation screen.
51 52 53 |
# File 'app/controllers/deliveries_controller.rb', line 51 def palletization flash[:info] = 'Pallets and other containers detected, please confirm assignment. Pallets can contain items but also other non-pallet containers.' end |
#pending_confirm ⇒ void
This method returns an undefined value.
Moves a shipped delivery to pending-confirm state.
980 981 982 983 |
# File 'app/controllers/deliveries_controller.rb', line 980 def pending_confirm @delivery.pending_confirm! if @delivery.shipped? redirect_to_return_path_or_default delivery_path(@delivery) end |
#pick_slip ⇒ void
This method returns an undefined value.
Streams the packing-slip PDF for the delivery (?split_kits=1 splits kits).
612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 |
# File 'app/controllers/deliveries_controller.rb', line 612 def pick_slip @delivery = Delivery.find(params[:id]) split_kits = params[:split_kits].to_b respond_to do |format| format.pdf do pdf_generator = Pdf::Document::PackingSlip.new(@delivery, { split_kits: split_kits, skip_plans: false }) pdf_data = pdf_generator.call send_data pdf_data, filename: @delivery.pick_slip_file_name, type: 'application/pdf', disposition: 'inline' end end end |
#picked ⇒ void
This method returns an undefined value.
Renders the picking/packing screen; FBA-locked deliveries skip straight to
pending ship-label.
38 39 40 41 42 43 44 45 46 47 |
# File 'app/controllers/deliveries_controller.rb', line 38 def picked if @delivery.locked_for_fba? complete_picked_action(true) # just go to pending_ship_label and skip picking since we must be packed already else @delivery.repick if @delivery.can_repick? zero_out_shipment_weight = false zero_out_shipment_weight = true if @delivery&.order&.awaiting_deliveries? # here we want to force warehouse to enter *measured* weight when ship labeling, though not pre-packing render_picked_action(zero_out_shipment_weight) end end |
#print_booking_documents ⇒ Object
Pipe one booking document (bol | ci | package) to the selected print profile,
falling back to browser download when no profile is chosen. Reuses the same
handle_print_uploads pipeline as the ship-label screen.
774 775 776 777 778 779 780 781 782 |
# File 'app/controllers/deliveries_controller.rb', line 774 def print_booking_documents doc = booking_documents.detect { |d| d[:key] == params[:document] } if doc handle_print_uploads([], [doc[:upload]]) else flash[:error] = 'That document is not available for this delivery.' end redirect_to booking_summary_delivery_path(@delivery) end |
#print_pick_slip ⇒ Object
GET /customers/1/orders/1/print_pick_slip
706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 |
# File 'app/controllers/deliveries_controller.rb', line 706 def print_pick_slip @delivery.picking split_kits = params[:split_kits].to_b pdf = @delivery.generate_pick_slip_pdf(split_kits) if (print_profile = PrintProfile.where(id: params[:print_profile_id]).first) jid = print_profile.print_upload(pdf) flash[:info] = "Print Job #{jid} submitted to #{print_profile.name} [#{print_profile.id}]" else session[:download_path] = upload_url(pdf.id) session[:download_disposition] = :inline end if @delivery.should_print_heating_element_labels? redirect_to (delivery_id: @delivery.id, heating_elements_only: true, return_path: @return_path) else redirect_to_return_path_or_default delivery_path(@delivery, tab: 'shipping') end end |
#print_serial_numbers ⇒ void
This method returns an undefined value.
Generates the serial-numbers PDF for the delivery and redirects to it.
1008 1009 1010 1011 |
# File 'app/controllers/deliveries_controller.rb', line 1008 def print_serial_numbers pdf = @delivery.generate_serial_numbers_pdf redirect_to upload_path(pdf) end |
#purchase_marketplace_label ⇒ Object
Eager purchase of marketplace labels (Walmart, Amazon, etc.) before warehouse picks the order
This allows reporting tracking to marketplaces earlier
488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 |
# File 'app/controllers/deliveries_controller.rb', line 488 def purchase_marketplace_label # Check if this delivery supports marketplace label purchasing purchaser_class = Edi::MarketplaceLabelPurchaser.for_delivery(@delivery) unless purchaser_class flash[:error] = 'This delivery does not support marketplace label purchasing' redirect_to polymorphic_path(@ship_quotable, action: :shipping) and return end marketplace_name = Edi::MarketplaceLabelPurchaser.marketplace_name(@order) unless Edi::MarketplaceLabelPurchaser.marketplace_carrier?(@delivery.carrier) flash[:error] = "Please select a #{marketplace_name} shipping method first" redirect_to polymorphic_path(@ship_quotable, action: :shipping) and return end # Create shipments if they don't exist if @delivery.shipments.empty? Shipping::CreateSuggestedShipment.new.process(@delivery) @delivery.reload end # Get shipments that don't already have labels shipments_to_label = @delivery.shipments.reject { |s| s.tracking_number.present? } if shipments_to_label.empty? flash[:info] = 'All shipments already have labels' redirect_to polymorphic_path(@ship_quotable, action: :shipping) and return end # Get the rate data from selected shipping cost selected_shipping_cost = @delivery.selected_shipping_cost if selected_shipping_cost&.rate_data.blank? flash[:error] = "No #{marketplace_name} rate selected" redirect_to polymorphic_path(@ship_quotable, action: :shipping) and return end # Build marketplace-agnostic rate hash from rate_data rate_data = selected_shipping_cost.rate_data.with_indifferent_access rate = build_marketplace_rate(rate_data) success_count = 0 = [] shipments_to_label.each do |shipment| purchaser = purchaser_class.new(shipment) result = purchaser.purchase_label(rate) if result.success success_count += 1 shipment.label_generated! if shipment.can_label_generated? else << "Shipment #{shipment.id}: #{result.error}" end rescue StandardError => e << "Shipment #{shipment.id}: #{e.}" ErrorReporting.error(e, shipment_id: shipment.id, delivery_id: @delivery.id) end if success_count > 0 flash[:info] = "Purchased #{success_count} #{marketplace_name} label(s) successfully" # Update delivery with tracking info from first shipment first_labeled = @delivery.shipments.find { |s| s.tracking_number.present? } @delivery.update(master_tracking_number: first_labeled.tracking_number) if first_labeled end flash[:error] = .join('; ') if .any? redirect_to polymorphic_path(@ship_quotable, action: :shipping) end |
#recalculate_shipping ⇒ void
This method returns an undefined value.
Re-retrieves shipping costs for this delivery, persisting any submitted
ship-by/deliver-by dates (non-marketplace orders only) and honoring an
optional rate_ship_date override.
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 |
# File 'app/controllers/deliveries_controller.rb', line 138 def recalculate_shipping # Save deadline dates if provided in params (only for non-marketplace orders) # IMPORTANT: Do not overwrite dates for marketplace/EDI orders - these are retailer-provided is_marketplace_order = @ship_quotable.try(:edi_orchestrator_partner).present? unless is_marketplace_order if params[:requested_ship_before].present? || params[:requested_deliver_by].present? @ship_quotable.requested_ship_before = params[:requested_ship_before] if params[:requested_ship_before].present? @ship_quotable.requested_deliver_by = params[:requested_deliver_by] if params[:requested_deliver_by].present? @ship_quotable.save end end # Ensure delivery is in quoting state before retrieving costs if @delivery.state != 'quoting' Rails.logger.warn("[RecalculateShipping] Delivery #{@delivery.id} is in state '#{@delivery.state}', transitioning to 'quoting'") @delivery.back_to_quoting! if @delivery.can_back_to_quoting? end # Parse rate_ship_date if provided (user can override the ship date for rate calculation) rate_ship_date = nil if params[:rate_ship_date].present? rate_ship_date = begin Date.parse(params[:rate_ship_date]) rescue StandardError nil end # Ensure it's not in the past rate_ship_date = nil if rate_ship_date && rate_ship_date < Date.current end result = @delivery.retrieve_shipping_costs(rate_ship_date: rate_ship_date) Rails.logger.info("[RecalculateShipping] Delivery #{@delivery.id} retrieve_shipping_costs result: #{result.inspect}") @ship_quotable.do_not_detect_shipping = true @ship_quotable.last_shipping_rate_request_result = @ship_quotable.deliveries.where(state: 'quoting').map(&:last_shipping_rate_request_result) @ship_quotable.save # puts "recalculate_shipping test end time: #{Time.current}" # puts "recalculate_shipping test processing time = #{Time.current - start}" redirect_to polymorphic_path(@ship_quotable, action: :shipping, shipping_updated: true) end |
#recalculate_shipping_all ⇒ void
This method returns an undefined value.
Re-retrieves shipping costs for all deliveries of the order/quote.
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 |
# File 'app/controllers/deliveries_controller.rb', line 181 def recalculate_shipping_all # Save deadline dates if provided in params (only for non-marketplace orders) # IMPORTANT: Do not overwrite dates for marketplace/EDI orders - these are retailer-provided if @ship_quotable.try(:edi_orchestrator_partner).blank? if params[:requested_ship_before].present? || params[:requested_deliver_by].present? @ship_quotable.requested_ship_before = params[:requested_ship_before] if params[:requested_ship_before].present? @ship_quotable.requested_deliver_by = params[:requested_deliver_by] if params[:requested_deliver_by].present? @ship_quotable.save end end # Parse rate_ship_date if provided (user can override the ship date for rate calculation) rate_ship_date = nil if params[:rate_ship_date].present? rate_ship_date = begin Date.parse(params[:rate_ship_date]) rescue StandardError nil end # Ensure it's not in the past rate_ship_date = nil if rate_ship_date && rate_ship_date < Date.current end @ship_quotable.retrieve_shipping_costs(rate_ship_date: rate_ship_date) redirect_to polymorphic_path(@ship_quotable, action: :shipping, shipping_updated: true) end |
#release ⇒ void
This method returns an undefined value.
Releases the delivery from a scheduled future release.
743 744 745 746 747 |
# File 'app/controllers/deliveries_controller.rb', line 743 def release @delivery.override_future_release_date = '1' @delivery.release! redirect_to_return_path_or_default delivery_path(@delivery) end |
#request_estimated_packaging ⇒ void
This method returns an undefined value.
Moves the delivery (or its quote) into the pre-pack / estimated-packaging
request flow.
1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 |
# File 'app/controllers/deliveries_controller.rb', line 1112 def request_estimated_packaging @delivery.prepack_requester = current_user if @delivery.update(params[:delivery] || {}) && (@delivery.quote || @delivery).request_estimated_packaging # quote needs to go to pre_pack, order has separate flows for pre_pack to carrier assignment etc and we only set the order delivery to be in pre_pack flash[:info] = "Status updated to #{@delivery.human_state_name}" redirect_to_return_path_or_default delivery_path(@delivery) else flash[:error] = @delivery.errors_to_s redirect_to_return_path_or_default delivery_path(@delivery) end end |
#retry_asynch_carrier_confirm ⇒ void
This method returns an undefined value.
Re-enqueues the asynchronous Freightquote load-number confirmation for a
delivery still pending carrier confirm.
910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 |
# File 'app/controllers/deliveries_controller.rb', line 910 def retry_asynch_carrier_confirm @return_path = delivery_path(@delivery) if @delivery.carrier == 'Freightquote' && @delivery.pending_carrier_confirm? job_id = GetFreightquoteLoadNumber.perform_async({ delivery_id: @delivery.id, current_user_id: @context_user.id }.deep_stringify_keys) if job_id redirect_to job_path(job_id) else @delivery.errors.add(:base, 'Unable to retry asynchronous carrier confirm, please contact a member of the IT team for assistance') redirect_to_return_path_or_default delivery_path(@delivery) end else flash[:info] = "Delivery #{view_context.link_to(@delivery.reference_number, delivery_path(@delivery))} does not need asynchronous carrier confirmation" redirect_to_return_path_or_default delivery_path(@delivery) end end |
#saturday_delivery ⇒ void
This method returns an undefined value.
Enables Saturday delivery and recalculates shipping.
346 347 348 349 350 351 352 |
# File 'app/controllers/deliveries_controller.rb', line 346 def saturday_delivery @ship_quotable.saturday_delivery = true @ship_quotable.need_to_recalculate_shipping @ship_quotable.save! err_msg = MessagingLog.(@delivery.messaging_logs) redirect_to polymorphic_path(@ship_quotable, action: :shipping, shipping_updated: true, shipping_update_type: 'saturday_delivery'), flash: { error: err_msg } end |
#selected_shipping_account_number_id_from_params ⇒ String?
Extract the submitted shipping_account_number_id for the shipping_cost
row identified by params[:shipping_cost_id] out of the nested
deliveries/shipping_costs attributes.
251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 |
# File 'app/controllers/deliveries_controller.rb', line 251 def selected_shipping_account_number_id_from_params return nil unless @ship_quotable root = params[@ship_quotable.model_name.param_key] return nil unless root.respond_to?(:to_unsafe_h) deliveries = root.to_unsafe_h[:deliveries_attributes] return nil unless deliveries.respond_to?(:each_value) target = params[:shipping_cost_id].to_s deliveries.each_value do |delivery_attrs| scs = delivery_attrs.is_a?(Hash) ? delivery_attrs[:shipping_costs_attributes] : nil next unless scs.respond_to?(:each_value) scs.each_value do |sc_attrs| next unless sc_attrs.is_a?(Hash) return sc_attrs[:shipping_account_number_id].to_s if sc_attrs[:id].to_s == target end end nil end |
#serial_numbers ⇒ void
This method returns an undefined value.
Streams the serial-number label PDF for the delivery.
1015 1016 1017 1018 1019 1020 |
# File 'app/controllers/deliveries_controller.rb', line 1015 def serial_numbers @delivery = Delivery.find(params[:id]) serial_numbers = @delivery.serial_numbers_to_print result = Pdf::Label::SerialNumber.call(serial_numbers) send_data result.pdf, filename: 'serial_numbers.pdf', type: 'application/pdf', disposition: 'inline' end |
#ship_label ⇒ void
This method returns an undefined value.
Renders the ship-label screen.
758 |
# File 'app/controllers/deliveries_controller.rb', line 758 def ship_label; end |
#shipped ⇒ void
This method returns an undefined value.
Marks the delivery as shipped.
970 971 972 973 974 975 976 |
# File 'app/controllers/deliveries_controller.rb', line 970 def shipped flash[:error] = 'Delivery could not be marked shipped: perhaps no PRO/tracking numbers?' unless @delivery.shipped redirect_to_return_path_or_default delivery_path(@delivery) rescue RuntimeError => e flash[:error] = e. redirect_to_return_path_or_default delivery_path(@delivery) end |
#show ⇒ Object
GET /deliveries/1
GET /deliveries/1.xml
598 599 600 601 602 603 604 605 606 607 608 |
# File 'app/controllers/deliveries_controller.rb', line 598 def show @delivery = Delivery.includes(line_items: [:item]).find(params[:id]) if @delivery.nil? redirect_to(@delivery.resource, notice: 'Delivery was cancelled, please see order or quote.') else respond_to do |format| format.html # show.html.erb format.xml { render xml: @delivery } end end end |
#show_shipment_content ⇒ void
This method returns an undefined value.
Renders the read-only shipment-contents view.
1024 1025 1026 |
# File 'app/controllers/deliveries_controller.rb', line 1024 def show_shipment_content @delivery = Delivery.find(params[:id]) end |
#signature_confirmation ⇒ void
This method returns an undefined value.
Enables signature confirmation and recalculates shipping.
366 367 368 369 370 371 372 |
# File 'app/controllers/deliveries_controller.rb', line 366 def signature_confirmation @ship_quotable.signature_confirmation = true @ship_quotable.need_to_recalculate_shipping @ship_quotable.save! err_msg = MessagingLog.(@delivery.messaging_logs) redirect_to polymorphic_path(@ship_quotable, action: :shipping, shipping_updated: true, shipping_update_type: 'signature_confirmation'), flash: { error: err_msg } end |
#single_origin ⇒ void
This method returns an undefined value.
Switches the order/quote to single-origin shipping and recalculates.
210 211 212 213 214 |
# File 'app/controllers/deliveries_controller.rb', line 210 def single_origin @ship_quotable.need_to_recalculate_shipping @ship_quotable.update(ltl_freight: false, ltl_freight_guaranteed: false, single_origin: true) redirect_to polymorphic_path(@ship_quotable, action: :shipping, shipping_updated: true) end |
#switch_ships_economy_carrier ⇒ void
This method returns an undefined value.
Saves the chosen economy carrier and applies the matching shipping rate.
1129 1130 1131 1132 1133 1134 1135 1136 1137 |
# File 'app/controllers/deliveries_controller.rb', line 1129 def switch_ships_economy_carrier if @delivery.update(params[:delivery] || {}) @delivery.apply_shipping_match_for_economy_shipping redirect_to ship_label_delivery_path(@delivery) else flash.now[:error] = @delivery.errors_to_s.presence || 'Could not switch shipping economy carrier.' render :choose_ships_economy_carrier, status: :unprocessable_content end end |
#tab_account_ledger ⇒ void
This method returns an undefined value.
Renders the account-ledger tab fragment for a delivery.
1213 1214 1215 1216 1217 1218 1219 |
# File 'app/controllers/deliveries_controller.rb', line 1213 def tab_account_ledger (:read, @delivery) respond_to do |format| format.html { render layout: should_render_layout? } format.turbo_stream end end |
#tab_freight_events ⇒ void
This method returns an undefined value.
Renders the freight-events tab fragment for a delivery.
1233 1234 1235 1236 1237 1238 1239 |
# File 'app/controllers/deliveries_controller.rb', line 1233 def tab_freight_events (:read, @delivery) respond_to do |format| format.html { render layout: should_render_layout? } format.turbo_stream end end |
#tab_invoices ⇒ void
This method returns an undefined value.
Renders the invoices tab fragment for a delivery.
1193 1194 1195 1196 1197 1198 1199 |
# File 'app/controllers/deliveries_controller.rb', line 1193 def tab_invoices (:read, @delivery) respond_to do |format| format.html { render layout: should_render_layout? } format.turbo_stream end end |
#tab_item_ledger ⇒ void
This method returns an undefined value.
Renders the item-ledger tab fragment for a delivery.
1203 1204 1205 1206 1207 1208 1209 |
# File 'app/controllers/deliveries_controller.rb', line 1203 def tab_item_ledger (:read, @delivery) respond_to do |format| format.html { render layout: should_render_layout? } format.turbo_stream end end |
#tab_line_items ⇒ void
This method returns an undefined value.
Renders the line-items tab fragment for a delivery.
1183 1184 1185 1186 1187 1188 1189 |
# File 'app/controllers/deliveries_controller.rb', line 1183 def tab_line_items (:read, @delivery) respond_to do |format| format.html { render layout: should_render_layout? } format.turbo_stream end end |
#tab_main ⇒ Object
Tab actions for turbo-tabs lazy loading.
Streamed pattern (PR #903) — every tab serves both formats so in-pane
interactions can target tab_frame_id via turbo_stream.update without
falling through to the empty-shell handler in turbo_stream_actions.js.
1162 1163 1164 1165 1166 1167 1168 1169 |
# File 'app/controllers/deliveries_controller.rb', line 1162 def tab_main (:read, @delivery) @delivery_presenter = DeliveryPresenter.new(@delivery, view_context) respond_to do |format| format.html { render layout: should_render_layout? } format.turbo_stream end end |
#tab_shipping ⇒ void
This method returns an undefined value.
Renders the shipping tab fragment for a delivery.
1173 1174 1175 1176 1177 1178 1179 |
# File 'app/controllers/deliveries_controller.rb', line 1173 def tab_shipping (:read, @delivery) respond_to do |format| format.html { render layout: should_render_layout? } format.turbo_stream end end |
#tab_shipping_api_log ⇒ void
This method returns an undefined value.
Renders the shipping API log tab fragment for a delivery.
1223 1224 1225 1226 1227 1228 1229 |
# File 'app/controllers/deliveries_controller.rb', line 1223 def tab_shipping_api_log (:read, @delivery) respond_to do |format| format.html { render layout: should_render_layout? } format.turbo_stream end end |
#tab_tracking_events ⇒ void
This method returns an undefined value.
Renders the tracking-events tab fragment for a delivery.
1243 1244 1245 1246 1247 1248 1249 |
# File 'app/controllers/deliveries_controller.rb', line 1243 def tab_tracking_events (:read, @delivery) respond_to do |format| format.html { render layout: should_render_layout? } format.turbo_stream end end |
#trigger_invoiced ⇒ void
This method returns an undefined value.
Triggers invoice creation for a shipped delivery.
987 988 989 990 991 992 993 994 |
# File 'app/controllers/deliveries_controller.rb', line 987 def trigger_invoiced # Advisory locking is handled by CreateInvoiceFromDelivery service @delivery.trigger_invoiced! if @delivery.shipped? rescue StandardError => e flash[:error] = "Could not create invoice: #{e.}" ensure redirect_to_return_path_or_default delivery_path(@delivery) end |
#undismiss_problematic ⇒ Object
Reverses warehouse "Dismiss" (Crm::WarehousesController#dismiss_problematic_shipment)
for every parcel on the delivery: clears the dismissal stamps so the
ProblematicDeliverySweep flags, alerts, and badges them again.
999 1000 1001 1002 1003 1004 |
# File 'app/controllers/deliveries_controller.rb', line 999 def undismiss_problematic count = @delivery.shipments.where.not(problematic_dismissed_at: nil) .update_all(problematic_dismissed_at: nil, problematic_dismissed_by_id: nil) flash[:info] = "Restored problematic-delivery monitoring on #{count} #{'parcel'.pluralize(count)}." redirect_to_return_path_or_default delivery_path(@delivery) end |
#update ⇒ Object
PUT /deliveries/1
PUT /deliveries/1.xml
691 692 693 694 695 696 697 698 699 700 701 702 703 |
# File 'app/controllers/deliveries_controller.rb', line 691 def update @delivery = Delivery.find(params[:id]) respond_to do |format| if @delivery.update(params[:delivery]) format.html { redirect_to(@delivery, notice: 'Delivery was successfully updated.') } format.xml { head :ok } else format.html { render action: 'edit', status: :unprocessable_content } format.xml { render xml: @delivery.errors, status: :unprocessable_content } end end end |
#update_release_date ⇒ Object
TODO
649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 |
# File 'app/controllers/deliveries_controller.rb', line 649 def update_release_date @delivery.future_release_date = params[:delivery][:future_release_date] @delivery.manual_release_only = params[:delivery][:manual_release_only] @delivery.do_not_reserve_stock = params[:delivery][:do_not_reserve_stock] if @delivery.save unless (@order.future_release_date == @delivery.future_release_date) && (@order.manual_release_only == @delivery.manual_release_only) && (@order.do_not_reserve_stock == @delivery.do_not_reserve_stock) @order.update( future_release_date: @delivery.future_release_date, manual_release_only: @delivery.manual_release_only, do_not_reserve_stock: @delivery.do_not_reserve_stock ) end @delivery.schedule_for_future_release! if @delivery.can_schedule_for_future_release? if @delivery.do_not_reserve_stock? && @delivery.order.has_committed_line_items? @delivery.uncommit_catalog_items elsif !@delivery.do_not_reserve_stock? && !@delivery.order.has_committed_line_items? @delivery.commit_catalog_items end redirect_to_return_path_or_default delivery_path(@delivery) else render action: 'edit_release_date', status: :unprocessable_content end end |
#update_shipping_cost ⇒ void
This method returns an undefined value.
Applies the shipping-cost selection submitted from the rate screen.
226 227 228 |
# File 'app/controllers/deliveries_controller.rb', line 226 def update_shipping_cost update_shipping_cost_data end |
#update_shipping_cost_account_number ⇒ void
This method returns an undefined value.
Applies a shipping-account-number (SAN) change for a shipping cost,
extracting the nested value from the form payload.
233 234 235 236 237 238 239 240 241 242 243 244 |
# File 'app/controllers/deliveries_controller.rb', line 233 def update_shipping_cost_account_number # The SAN <select> is a NESTED field # (<itemizable>[deliveries_attributes][i][shipping_costs_attributes][j][shipping_account_number_id]). # The observe-field Stimulus controller submits the WHOLE form, so the # changed value never arrives as top-level `params[:shipping_account_number_id]` # — it's nested under the row that fired the change. Pull it out by # matching the shipping_cost id. Returns "" for the blank # "<store> <carrier> account" de-select option, the id when one is # selected, or nil if the row isn't in the payload (leave SAN untouched). san_id = selected_shipping_account_number_id_from_params update_shipping_cost_data(!san_id.nil?, san_id) end |
#update_shipping_cost_data(force_shipping_account_number = false, shipping_account_number_id = nil) ⇒ Boolean
Selects the shipping cost identified by params[:shipping_cost_id] on the
delivery, optionally updating its shipping account number, via
Shipping::UpdateShippingMethod.
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 330 331 332 333 334 335 336 337 338 339 340 341 342 |
# File 'app/controllers/deliveries_controller.rb', line 279 def update_shipping_cost_data(force_shipping_account_number = false, shipping_account_number_id = nil) @updated = false @shipping_cost = @delivery.shipping_costs.find { |sc| sc.id == params[:shipping_cost_id].to_i } if @shipping_cost if WyShipping::AMAZON_BUY_SHIPPING_ADMIN_ONLY && @shipping_cost.is_amzbs? && !current_account&.is_admin? flash.now[:error] = 'Only administrators can select Amazon Buy Shipping rates.' return true end # Apply the account-number selection from the rate screen. The # selector's blank option ("<store> <carrier> account") DE-selects the # SAN — back to prepaid on our account — so we must assign even when # blank (→ nil), not only when present; otherwise de-selecting left the # SAN attached and the shipping line stuck at $0 (calculated_cost # zeroes on an attached SAN). Assign the ASSOCIATION (not the bare _id) # so the in-memory object — and the re-rendered cost cell — reflect the # change without a stale association cache. Saving fires # ShippingCost#set_line_items_price, which re-prices any shipping line # owned by THIS cost from the now-current calculated_cost. if force_shipping_account_number san = shipping_account_number_id.presence && ShippingAccountNumber.find_by(id: shipping_account_number_id) @shipping_cost.shipping_account_number = san || nil @shipping_cost.save # Changing the account on a NON-selected option must only update that # option's quoted-cost display — it must NOT switch the order's chosen # shipping method. update_from_shipping_cost SELECTS whatever cost it's # given, so only run it when this cost is already the selected one. # (set_line_items_price above is a no-op for a non-selected cost — it # owns no shipping line items — so the order line/total are untouched.) unless @shipping_cost.id == @delivery.selected_shipping_cost_id @updated = true @shipping_cost.reload return true end # Account changed on the SELECTED option: keep it selected, but # re-price its order line + recompute totals below. @delivery.update_column(:shipping_account_number_id, san&.id) end # Use the service to handle the complete shipping update flow # This captures the old method BEFORE making changes, then handles consequences AFTER result = Shipping::UpdateShippingMethod.new.update_from_shipping_cost(@delivery, @shipping_cost, @ship_quotable) if result.success? @updated = true # Render the streamed cell + totals from freshly persisted state. The # service only reloads the itemizable when the SELECTED option id # changes; changing the SAN on the already-selected option still # re-prices the shipping line, so reload here regardless. @shipping_cost.reload @ship_quotable&.reload result..each do |msg| flash.now[:info] = msg end else flash.now[:error] = result.errors end else flash.now[:error] = "Could not update shipping cost. Shipping cost #{params[:shipping_cost_id]} not found." end true end |
#update_tracking ⇒ void
This method returns an undefined value.
Saves tracking changes: a master tracking number applied to all completed
shipments atomically, or a regular delivery update (sending the commercial
invoice when an LTL PRO number arrives after invoicing).
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 |
# File 'app/controllers/deliveries_controller.rb', line 94 def update_tracking # The override checkbox lives on the delivery, but the format check runs # per shipment — TrackingNumberFormatValidator reads the flag off the # shipment's delivery. @delivery.skip_tracking_number_validation = params.dig(:delivery, :skip_tracking_number_validation) if (tn = params.dig(:master_tracking, :tracking_number)).present? shipments = @delivery.shipments.completed.to_a # `update`, not `update_attribute!` — the latter skips validations, which # is how unusable tracking numbers used to get in through this door. # # Every shipment is attempted (no short-circuit) so the operator sees ALL # validation errors at once, and the whole set rolls back if any fails — # otherwise a mid-list failure left earlier shipments persisted with the # new number while the response reported failure. updated_all = true Delivery.transaction do shipments.each { |s| updated_all = s.update(tracking_number: tn) && updated_all } raise ActiveRecord::Rollback unless updated_all end if updated_all flash[:info] = "Delivery #{delivery_link} tracking updated for all completed shipments" redirect_to_return_path_or_default delivery_path(@delivery) else shipments.flat_map { |s| s.errors. }.uniq.each { |m| @delivery.errors.add(:base, m) } render :edit_tracking, status: :unprocessable_content end elsif @delivery.update(params[:delivery] || {}) sending_commercial_invoice = false if @delivery.ships_ltl_freight? && @delivery.ltl_pro_number_changed? && @delivery.invoiced? # This is the scenario where the LTL PRO number was provided by the LTL truck driver and populated by warehouse staff after the load pickup, so now send_commercial_invoice_to_carrier (if it should be done) now that we have the PRO and the delivery's after_transition to invoiced did not send it. @delivery.send_commercial_invoice_to_carrier if @delivery.should_send_commercial_invoice_to_carrier? sending_commercial_invoice = true if @delivery.should_send_commercial_invoice_to_carrier? end flash[:info] = "Delivery #{delivery_link} tracking updated#{', attempting to send commercial invoice to carrier!' if sending_commercial_invoice}" redirect_to_return_path_or_default delivery_path(@delivery) else render :edit_tracking, status: :unprocessable_content end end |
#void_shipments ⇒ void
This method returns an undefined value.
Renders the void-shipments confirmation form.
946 |
# File 'app/controllers/deliveries_controller.rb', line 946 def void_shipments; end |