Class: Crm::Reports::InventoryPlanningController
- Inherits:
-
ReportsController
- Object
- ReportsController
- Crm::Reports::InventoryPlanningController
- Defined in:
- app/controllers/crm/reports/inventory_planning_controller.rb
Overview
Controller: inventory planning.
Instance Method Summary collapse
-
#generate_po ⇒ Object
Generates a purchase order or store transfer draft from the selected reorder items, stashing it server-side and redirecting to the builder.
-
#refresh_forecast ⇒ Object
Enqueues the item demand forecast refresh worker.
-
#refresh_report ⇒ Object
Enqueues the inventory plan refresh worker.
-
#render_errors(errors) ⇒ void
Re-renders #show with the given errors flashed.
-
#show ⇒ Object
Runs the inventory planning report, or (if forecast data hasn't been generated yet) surfaces the in-progress refresh job.
-
#show_chart ⇒ Object
Renders a single item's demand chart, layout-free (for a modal/panel).
Instance Method Details
#generate_po ⇒ Object
Generates a purchase order or store transfer draft from the selected
reorder items, stashing it server-side and redirecting to the builder.
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 |
# File 'app/controllers/crm/reports/inventory_planning_controller.rb', line 48 def generate_po errors = [] selected_items = params[:items].to_h.select { |_item_id, details| details['order'].to_b } errors << 'Must select one or more items' if selected_items.empty? errors << 'Must specify reorder quantity for selected items' if selected_items.any? { |_item_id, details| details['quantity'].blank? } if params[:commit] == 'Generate Purchase Order' supplier_ids = Item.where(id: selected_items.keys).distinct.pluck(:preferred_supplier_id) errors << 'Items selected must all be for the same supplier' if supplier_ids.length > 1 render_errors(errors) and return if errors.any? supplier = Supplier.find(supplier_ids[0]) date = Date.current.to_s po_params = { company_id: Company::USA, store_id: Store::WARMLYYOURS_US_ID, po_type: 'purchase', supplier_id: supplier.id, carrier_id: supplier.id, terms: supplier.terms, currency: supplier.currency, order_date: date, request_date: date } item_params = {} selected_items.each_with_index do |(item_id, details), index| si = supplier.supplier_items.where(item_id: item_id).first qty = si.uom_quantity.to_f.zero? ? 0 : (details['quantity'].to_i / si.uom_quantity.to_f).ceil unit_quantity = si.uom_quantity.to_f.zero? ? 0 : (details['quantity'].to_i / si.uom_quantity.to_f).ceil * si.uom_quantity unit_cost = si.current_price.try(:purchasing_cost) unit_weight = si.item.base_weight * si.uom_quantity item_params[index] = { stock_item: '1', sku: si.item.sku, item_id: item_id, description: si.item.name, supplier_sku: si.supplier_sku, supplier_description: si.supplier_description, uom: si.uom, quantity: qty, unit_quantity: unit_quantity, unit_weight: unit_weight, total_weight: (unit_weight * qty).round(2), unit_cost: unit_cost.to_s, total_cost: (unit_cost * qty).round(2), auto_receive: si.auto_receive? ? 1 : 0 } end po_params[:purchase_order_items_attributes] = item_params # Stash the draft server-side and redirect so Turbo Drive performs a # proper navigation. Can't pass the full nested payload via query string # (risks exceeding URL limits for larger orders) and purchase_orders#new # already builds from params[:purchase_order]. session[:inventory_planning_po_draft] = po_params # ApplicationController#redirect_to auto-promotes to 303 on POSTs. redirect_to new_purchase_order_path elsif params[:commit] == 'Generate Store Transfer' store = Store.find(Store::WARMLYYOURS_US_ID) new_store = Store.find(Store::WARMLYYOURS_CA_ID) # Stash items_list server-side so we don't risk 414 URI Too Long when # the user selected many SKUs. item_ledger_entries#store_transfer picks # the draft up if no items_list is present on the URL. session[:inventory_planning_store_transfer_draft] = selected_items.transform_values { |details| details['quantity'].to_i } redirect_to store_transfer_item_ledger_entries_path(options: { store_id: store.id, new_store_id: new_store.id, destination_address_id: new_store.consignee_party.addresses.first&.id }.compact) end end |
#refresh_forecast ⇒ Object
Enqueues the item demand forecast refresh worker.
28 29 30 31 |
# File 'app/controllers/crm/reports/inventory_planning_controller.rb', line 28 def refresh_forecast job_id = RefreshInventoryReportWorker.perform_async redirect_to_job_or_fallback(job_id, reports_inventory_planning_report_path) end |
#refresh_report ⇒ Object
Enqueues the inventory plan refresh worker.
34 35 36 37 |
# File 'app/controllers/crm/reports/inventory_planning_controller.rb', line 34 def refresh_report job_id = RefreshInventoryPlanWorker.perform_async redirect_to_job_or_fallback(job_id, reports_inventory_planning_report_path) end |
#render_errors(errors) ⇒ void
This method returns an undefined value.
Re-renders #show with the given errors flashed.
117 118 119 120 121 122 123 |
# File 'app/controllers/crm/reports/inventory_planning_controller.rb', line 117 def render_errors(errors) flash.now[:error] = errors.join(', ') params[:q] = params[:q].nil? ? nil : YAML.load(params[:q].gsub('=>', ':')).symbolize_keys params[:report_command] = params[:report_command].nil? ? nil : YAML.load(params[:report_command].gsub('=>', ':')).symbolize_keys show render :show, status: :unprocessable_content end |
#show ⇒ Object
Runs the inventory planning report, or (if forecast data hasn't been
generated yet) surfaces the in-progress refresh job.
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'app/controllers/crm/reports/inventory_planning_controller.rb', line 8 def show if ItemDemandForecast.any? params[:q] ||= {} params[:report_command] ||= {} params[:q][:product_category_ids_overlap_array] = params[:report_command][:product_category_ids] params[:q][:product_line_ids_overlap_array] = params[:report_command][:product_line_ids] @report_command = ::Report::InventoryPlanningCommand.new(params[:report_command]) @q = @report_command.execute.ransack(params[:q]) @q.sorts = 'item_sku asc' if @q.sorts.blank? @inventory_plans = @q.result @country = @report_command.country @country_only = @country.gsub('_st', '') else @report_refreshing = true # report is being refreshed, so find the job, could be working or still queued @job_id = BackgroundJobStatus.search(worker_klass: 'RefreshInventoryReportWorker').first&.jid end end |
#show_chart ⇒ Object
Renders a single item's demand chart, layout-free (for a modal/panel).
40 41 42 43 44 |
# File 'app/controllers/crm/reports/inventory_planning_controller.rb', line 40 def show_chart @item = Item.find(params[:item_id]) @country = params[:country] render layout: false end |