Class: AccountingDashboardController
- Inherits:
-
CrmController
- Object
- ActionController::Base
- ApplicationController
- CrmController
- AccountingDashboardController
- Defined in:
- app/controllers/accounting_dashboard_controller.rb
Overview
Controller: accounting dashboard.
Constant Summary
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
Constants included from Www::SeoHelper
Www::SeoHelper::AWARDS, Www::SeoHelper::CA_ADDRESS, Www::SeoHelper::CA_BUSINESS_HOURS, Www::SeoHelper::CA_CONTACT_POINT, Www::SeoHelper::CA_CURRENCIES, Www::SeoHelper::CA_DESCRIPTION, Www::SeoHelper::CA_FOUNDING_DATE, Www::SeoHelper::CA_GLOBAL_LOCATION_NUMBER, Www::SeoHelper::CA_LEGAL_NAME, Www::SeoHelper::CA_LOCAL_BUSINESS, Www::SeoHelper::CA_ONLINE_STORE, Www::SeoHelper::CA_RETURN_POLICY, Www::SeoHelper::CA_SALES_DEPARTMENT, Www::SeoHelper::CA_SERVICE_AREA, Www::SeoHelper::CA_URL, Www::SeoHelper::CA_VAT_ID, Www::SeoHelper::CA_WAREHOUSE_DEPARTMENT, Www::SeoHelper::CA_WAREHOUSE_HOURS, Www::SeoHelper::COMPANY_EMAIL, Www::SeoHelper::COMPANY_LOGO, Www::SeoHelper::COMPANY_NAME, Www::SeoHelper::COMPANY_SLOGAN, Www::SeoHelper::EXPERTISE, Www::SeoHelper::FAX_NUMBER, Www::SeoHelper::GS1_COMPANY_PREFIX, Www::SeoHelper::ISO6523_CODE, Www::SeoHelper::PAYMENT_METHODS, Www::SeoHelper::PHONE_NUMBER, Www::SeoHelper::PRIMARY_NAICS, Www::SeoHelper::REFUND_TYPE, Www::SeoHelper::RETURN_FEES, Www::SeoHelper::RETURN_METHOD, Www::SeoHelper::RETURN_POLICY_CATEGORY, Www::SeoHelper::SECONDARY_NAICS, Www::SeoHelper::SOCIAL_PROFILES, Www::SeoHelper::US_ADDRESS, Www::SeoHelper::US_BUSINESS_HOURS, Www::SeoHelper::US_CONTACT_POINT, Www::SeoHelper::US_CURRENCIES, Www::SeoHelper::US_DESCRIPTION, Www::SeoHelper::US_FOUNDING_DATE, Www::SeoHelper::US_GLOBAL_LOCATION_NUMBER, Www::SeoHelper::US_IMAGE, Www::SeoHelper::US_LEGAL_NAME, Www::SeoHelper::US_LOCAL_BUSINESS, Www::SeoHelper::US_ONLINE_STORE, Www::SeoHelper::US_RETURN_POLICY, Www::SeoHelper::US_SALES_DEPARTMENT, Www::SeoHelper::US_SERVICE_AREA, Www::SeoHelper::US_TAX_ID, Www::SeoHelper::US_URL, Www::SeoHelper::US_WAREHOUSE_DEPARTMENT, Www::SeoHelper::US_WAREHOUSE_HOURS
Constants included from IconHelper
IconHelper::CUSTOM_ICON_MAP, IconHelper::CUSTOM_SVG_DIR, IconHelper::DEFAULT_FAMILY
Instance Method Summary collapse
-
#acknowledge_missing_edi_810 ⇒ Object
POST /accounting/acknowledge_missing_edi_810 — mass-mark the selected EDI-810-missing invoices as transmitted (effectively "we know about it, stop bothering us").
-
#bulk_regenerate_edi_810 ⇒ Object
POST /accounting/bulk_regenerate_edi_810 — re-fire the EDI-810 creation pipeline for every selected invoice via Edi::InvoiceEventProcessor.
-
#index ⇒ Object
GET /accounting — landing page for the accounting team's daily workflow.
-
#tab_count ⇒ Object
GET /accounting/tab_count — count-only endpoint behind each tab badge in the dashboard.
-
#tab_email_or_fax ⇒ Object
GET /accounting/tab_email_or_fax — turbo-frame body for the Email/Fax tab.
-
#tab_mail ⇒ Object
GET /accounting/tab_mail — turbo-frame body for the Mail tab (customers who require physical printed-and-mailed documents).
-
#tab_missing_edi_810 ⇒ Object
GET /accounting/tab_missing_edi_810 — turbo-frame body for the "EDI 810 missing" tab (invoices that should have transmitted as an EDI 810 but didn't).
-
#tab_mixed ⇒ Object
GET /accounting/tab_mixed — turbo-frame body for the Mixed tab (customers whose contact-points span more than one transmission channel, requiring per-doc handling).
-
#tab_no_channel_set ⇒ Object
GET /accounting/tab_no_channel_set — turbo-frame body for docs whose customer has no transmission channel configured at all.
-
#tab_portal ⇒ Object
GET /accounting/tab_portal — turbo-frame body for the Portal tab (customers whose docs are picked up via partner portal, e.g. SPS).
-
#tab_replacement_invoice ⇒ Object
GET /accounting/tab_replacement_invoice — turbo-frame body for the "replacement invoice" tab.
-
#transmissions ⇒ Object
GET /accounting/transmissions — combined queue view of every outbound accounting document (invoice, credit memo) waiting on transmission.
-
#transmit_accounting_documents ⇒ Object
POST /accounting/transmit_accounting_documents — bulk action on the documents the user checked off in the transmissions list.
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
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?, #stamp_impersonation_context, #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, #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 ApplicationHelper
#better_number_to_currency, #check_force_logout, #check_or_cross, #check_or_times, #embedded_tab_frame_id, #error_messages, #general_disclaimer_on_product_installation_and_local_codes, #gridjs_from_html_table, #gridjs_table, #is_wy_ip, #line_break, #parent_layout, #pass_or_fail, #render_error_messages_list, #render_video_card, #resolved_auth_form_turbo_frame, #return_path_or, #safe_css_color, #set_return_path_if_present, #set_section_if_present, #tab_frame_id, #to_underscore, #track_page?, #turbo_section_wrapper, #turbo_tabs_request?, #url_on_same_domain_as_request, #widget_index_daily_focus_index_path, #working_hours?, #yes_or_no, #yes_or_no_highlighted, #yes_or_no_with_check_or_cross, #youtube_video
Methods included from UppyUploaderHelper
#file_uploader, #image_uploader, #large_file_uploader_s3, #lead_sketch_uploader, #rma_image_uploader, #rma_image_uploader_s3, #uppy_uploader, #video_uploader
Methods included from Www::ImagesHelper
#image_asset_tag, #image_asset_url
Methods included from Www::SeoHelper
#add_page_schema, #add_webpage_schema, #canada?, #company_social_links, #ensure_context_json, #json_ld_script_tag, #local_business_schema, #online_store_id, #online_store_schema, #page_main_entity, #page_main_entity_json, #render_auto_collection_page_schema, #render_collection_page_schema, #render_local_business_schema, #render_online_store_schema, #render_page_schemas, #render_page_video_schemas, #render_webpage_schema, #render_webpage_schema_with_collections, #usa?
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?
Methods included from IconHelper
#account_nav_icon, #fa_icon, #star_rating_html
Instance Method Details
#acknowledge_missing_edi_810 ⇒ Object
POST /accounting/acknowledge_missing_edi_810 — mass-mark the
selected EDI-810-missing invoices as transmitted (effectively
"we know about it, stop bothering us"). Each invoice fires its
transmit! state-machine event when it's still in a
transmittable state.
162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'app/controllers/accounting_dashboard_controller.rb', line 162 def acknowledge_missing_edi_810 invoice_ids = params[:invoice_ids].to_a.map(&:to_i).reject(&:zero?) if invoice_ids.empty? flash[:warning] = 'No invoices selected.' else Invoice.transaction do Invoice.where(id: invoice_ids).find_each { |invoice| invoice.transmit! if invoice.can_transmit? } end flash[:info] = "#{invoice_ids.size} invoice(s) marked as ignored and removed from this list." end redirect_to accounting_transmissions_path(since: params[:since], tab: 'missing_edi_810') end |
#bulk_regenerate_edi_810 ⇒ Object
POST /accounting/bulk_regenerate_edi_810 — re-fire the EDI-810
creation pipeline for every selected invoice via
Edi::InvoiceEventProcessor. Bulk equivalent of the per-invoice
InvoicesController#regenerate_edi_documents action.
179 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'app/controllers/accounting_dashboard_controller.rb', line 179 def bulk_regenerate_edi_810 :update, Invoice invoice_ids = params[:invoice_ids].to_a.map(&:to_i).reject(&:zero?) if invoice_ids.empty? flash[:warning] = 'No invoices selected.' else processor = Edi::InvoiceEventProcessor.new Invoice.where(id: invoice_ids).find_each { |invoice| processor.process_creation(invoice) } flash[:info] = "EDI documents queued for regeneration on #{invoice_ids.size} invoice(s)." end redirect_to accounting_transmissions_path(since: params[:since], tab: 'missing_edi_810') end |
#index ⇒ Object
GET /accounting — landing page for the accounting team's daily
workflow. The page itself is mostly turbo-frame slots that fetch
the per-tab content lazily.
7 |
# File 'app/controllers/accounting_dashboard_controller.rb', line 7 def index; end |
#tab_count ⇒ Object
GET /accounting/tab_count — count-only endpoint behind each tab
badge in the dashboard. Returns just the integer count for the
requested tab, applying the same filter the corresponding tab
action would apply.
133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
# File 'app/controllers/accounting_dashboard_controller.rb', line 133 def tab_count q = params[:q].to_h @tab = params[:tab].to_s @count = case @tab when 'email_or_fax' ViewAccountingTransmission.ransack(q.merge('transmission_type_in' => ['Email/Fax'])).result.count when 'portal' ViewAccountingTransmission.ransack(q.merge('transmission_type_in' => ['Portal'])).result.count when 'mail' ViewAccountingTransmission.ransack(q.merge('transmission_type_in' => ['Mail'])).result.count when 'mixed' ViewAccountingTransmission.ransack(q.merge('transmission_type_not_in' => ['Email/Fax', 'Portal', 'Mail', 'No Channel Set'])).result.count when 'no_channel_set' ViewAccountingTransmission.ransack(q.merge('transmission_type_in' => ['No Channel Set'])).result.count when 'replacement_invoice' ViewAccountingTransmission.ransack(q.merge('doc_type_in' => ['INV'])).result.count when 'missing_edi_810' Invoice.missing_edi_810.where(invoices: { created_at: 90.days.ago.. }).count else 0 end render layout: false end |
#tab_email_or_fax ⇒ Object
GET /accounting/tab_email_or_fax — turbo-frame body for the
Email/Fax tab. Pulls every doc whose customer transmits via email
or fax, including the related Communications so the per-row
"transmission error" tooltip doesn't N+1.
63 64 65 66 67 68 69 70 71 72 |
# File 'app/controllers/accounting_dashboard_controller.rb', line 63 def tab_email_or_fax @email_fax_query = ViewAccountingTransmission.ransack(params[:q]) @email_fax_query.sorts = 'document_date asc' if @email_fax_query.sorts.empty? @email_fax_documents = @email_fax_query.result .except(:order) .order("#{@email_fax_query.sorts.first.name} #{@email_fax_query.sorts.first.dir} NULLS LAST") .load preload_unsent_communications(@email_fax_documents) render 'tab_email_or_fax', layout: should_render_layout? end |
#tab_mail ⇒ Object
GET /accounting/tab_mail — turbo-frame body for the Mail tab
(customers who require physical printed-and-mailed documents).
82 83 84 |
# File 'app/controllers/accounting_dashboard_controller.rb', line 82 def tab_mail render 'tab_mail', layout: should_render_layout? end |
#tab_missing_edi_810 ⇒ Object
GET /accounting/tab_missing_edi_810 — turbo-frame body for the
"EDI 810 missing" tab (invoices that should have transmitted as an
EDI 810 but didn't). Defaults to the last 90 days but takes a
since param to expand the window.
119 120 121 122 123 124 125 126 127 |
# File 'app/controllers/accounting_dashboard_controller.rb', line 119 def tab_missing_edi_810 @since = params[:since].present? ? Date.parse(params[:since]) : 90.days.ago.to_date @invoices = Invoice.missing_edi_810 .where(invoices: { created_at: @since.. }) .includes(:order, :customer) .order(created_at: :desc) .load render 'tab_missing_edi_810', layout: should_render_layout? end |
#tab_mixed ⇒ Object
GET /accounting/tab_mixed — turbo-frame body for the Mixed tab
(customers whose contact-points span more than one transmission
channel, requiring per-doc handling).
89 90 91 |
# File 'app/controllers/accounting_dashboard_controller.rb', line 89 def tab_mixed render 'tab_mixed', layout: should_render_layout? end |
#tab_no_channel_set ⇒ Object
GET /accounting/tab_no_channel_set — turbo-frame body for docs
whose customer has no transmission channel configured at all.
These need a setup task before they can move forward.
96 97 98 |
# File 'app/controllers/accounting_dashboard_controller.rb', line 96 def tab_no_channel_set render 'tab_no_channel_set', layout: should_render_layout? end |
#tab_portal ⇒ Object
GET /accounting/tab_portal — turbo-frame body for the Portal tab
(customers whose docs are picked up via partner portal, e.g. SPS).
76 77 78 |
# File 'app/controllers/accounting_dashboard_controller.rb', line 76 def tab_portal render 'tab_portal', layout: should_render_layout? end |
#tab_replacement_invoice ⇒ Object
GET /accounting/tab_replacement_invoice — turbo-frame body for
the "replacement invoice" tab. Shows full-RMA-funded INV docs
whose RMA is still awaiting return after 15+ days, so accounting
can chase the customer for the return or write it off.
104 105 106 107 108 109 110 111 112 113 |
# File 'app/controllers/accounting_dashboard_controller.rb', line 104 def tab_replacement_invoice @replacement_invoice_query = ViewAccountingTransmission.ransack(params[:q]) @replacement_invoice_query.sorts = 'document_date asc' if @replacement_invoice_query.sorts.empty? @replacement_invoice_documents = @replacement_invoice_query.result .except(:order) .order("#{@replacement_invoice_query.sorts.first.name} #{@replacement_invoice_query.sorts.first.dir} NULLS LAST") .load preload_unsent_communications(@replacement_invoice_documents) render 'tab_replacement_invoice', layout: should_render_layout? end |
#transmissions ⇒ Object
GET /accounting/transmissions — combined queue view of every
outbound accounting document (invoice, credit memo) waiting on
transmission. Each tab is rendered separately by the tab_*
actions; this action just sets up the shared search struct.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'app/controllers/accounting_dashboard_controller.rb', line 13 def transmissions params[:q] ||= {} # @tabs = { # email: {title: 'Email/Fax', query: {transmission_type_in: ['Email/Fax'], rma_funding_not_eq: 'full'}}, # portal: {title: 'Portal', query: {transmission_type_in: ['Portal'], rma_funding_not_eq: 'full'}}, # mail: {title: 'Mail', query: {transmission_type_in: ['Mail'], rma_funding_not_eq: 'full'}}, # mixed: {title: 'Mixed', query: {transmission_type_not_in: ['Email/Fax','Portal','Mail','No Channel Set'], rma_funding_not_eq: 'full'}}, # none: {title: 'No Channel Set', query: {transmission_type_in: ['No Channel Set'], rma_funding_not_eq: 'full'}}, # rma: {title: 'Replacement Invoice', query: {doc_type_in: ['INV'], rma_funding_eq: 'full', state_eq: 'unpaid', rma_state_eq: 'awaiting_return', document_date_lteq: 15.days.ago}} # } # @tabs.each {|tab, options| options[:count] = ViewAccountingTransmission.ransack(params[:q].merge(options[:query])).result.count} # @selected_tab = (params[:tab] || :email).to_sym @q = OpenStruct.new(params[:q]) end |
#transmit_accounting_documents ⇒ Object
POST /accounting/transmit_accounting_documents — bulk action on
the documents the user checked off in the transmissions list.
Three submit buttons land here: Transmit actually sends them,
Mark As Transmitted flips their state without sending,
Print produces a single combined PDF and exposes it via
session[:download_path] so the next page picks it up.
36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'app/controllers/accounting_dashboard_controller.rb', line 36 def transmit_accounting_documents redirect_to(accounting_transmissions_path(q: parsed_transmission_query, tab: params[:tab]), alert: 'You must select one or more documents') and return if params[:documents].nil? transmitter = AccountingDocumentTransmitter.new(params[:documents]) case params[:commit] when 'Transmit' result = transmitter.transmit flash[:info] = result[:success_message] flash[:warning] = result[:error_message] when 'Mark As Transmitted' transmitter.mark_transmitted flash[:info] = 'Selected documents have been marked as transmitted.' when 'Print' upload = transmitter.print_docs if upload.nil? flash[:error] = 'Unable to print documents' else session[:download_path] = upload_url(upload.id) end end redirect_to accounting_transmissions_path(q: parsed_transmission_query, tab: params[:tab]) end |