Class: Crm::TimeOffRequestsController
- Inherits:
-
CrmController
- Object
- ActionController::Base
- ApplicationController
- CrmController
- Crm::TimeOffRequestsController
- Includes:
- Controllers::Workflowable
- Defined in:
- app/controllers/crm/time_off_requests_controller.rb
Overview
CRUD for TimeOffRequest records, plus the balance calculator,
conflict/blocked-date lookups, and Google Calendar sync used by the
request form and detail page.
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
Instance Method Summary collapse
-
#create ⇒ void
Creates a time off request for the nested-route employee (never trusts a form-submitted employee_id).
-
#edit ⇒ void
Loads the request to edit via #prevent_past_edits and rebuilds the balance calculator/special-dates data for the form.
-
#index ⇒ void
Lists an employee's time off requests.
-
#new ⇒ void
Builds a new time off request and the balance calculator/special-dates data the form needs, redirecting if the employee has no active work schedule.
-
#retrieve_date_details ⇒ void
AJAX endpoint: computes the request-date breakdown (available dates, overlaps, time available) for the given date range and type.
-
#show ⇒ void
Shows a request with its blocked dates, holidays, conflicts, and Google Calendar sync status.
-
#sync_google_calendar ⇒ void
Pushes/pulls the request's Google Calendar event and redirects with the result.
-
#update ⇒ void
Updates the request loaded by #prevent_past_edits (never lets the employee change).
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
#create ⇒ void
This method returns an undefined value.
Creates a time off request for the nested-route employee (never trusts
a form-submitted employee_id).
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'app/controllers/crm/time_off_requests_controller.rb', line 96 def create @time_off_request = TimeOffRequest.new(params[:time_off_request]) # The employee is fixed by the nested route — never trust the form's # employee_id (a tampered POST could file a request under someone else). @time_off_request.employee_id = params[:employee_id] @employee = @time_off_request.employee @time_off_balances_view = TimeOffBalanceCalculator.new(employee: @employee, date: @time_off_request.start_date).formatted_balances @special_dates = fetch_special_dates(@employee) @work_schedule = @time_off_request.employee.work_schedules.effective_now.first if @time_off_request.save if @time_off_request.google_calendar_error.present? flash[:alert] = @time_off_request.google_calendar_error else flash[:notice] = 'Time-off request created successfully.' end redirect_to user_time_off_path(@employee, tab: "time_off_requests") else flash.now[:alert] = "Errors present: #{@time_off_request.errors..to_sentence}" render :new, status: :unprocessable_content end end |
#edit ⇒ void
This method returns an undefined value.
Loads the request to edit via #prevent_past_edits and rebuilds the
balance calculator/special-dates data for the form.
82 83 84 85 86 87 88 89 90 |
# File 'app/controllers/crm/time_off_requests_controller.rb', line 82 def edit @time_off_request = TimeOffRequest.find(params.expect(:id)) @employee = @time_off_request.employee @work_schedule = @employee.work_schedules.effective_now.first @special_dates = fetch_special_dates(@employee) # Call the balance calculator for all time off types as of today as_of_date = params[:calculator_date].present? ? Date.parse(params[:calculator_date]) : Date.current @time_off_balances_view = TimeOffBalanceCalculator.new(employee: @employee, date: as_of_date).formatted_balances end |
#index ⇒ void
This method returns an undefined value.
Lists an employee's time off requests.
14 15 16 17 |
# File 'app/controllers/crm/time_off_requests_controller.rb', line 14 def index @employee = Employee.find(params.expect(:employee_id)) @time_off_requests = @employee.time_off_requests end |
#new ⇒ void
This method returns an undefined value.
Builds a new time off request and the balance calculator/special-dates
data the form needs, redirecting if the employee has no active work
schedule.
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 |
# File 'app/controllers/crm/time_off_requests_controller.rb', line 52 def new redirect_to employees_path, error: 'Employee ID parameter not provided.' if params[:employee_id].blank? @employee = Employee.find(params.expect(:employee_id)) @work_schedule = @employee.work_schedules.effective_now.first if @work_schedule.present? @time_off_request = @employee.time_off_requests.new @time_off_request.time_off_request_dates.build @special_dates = fetch_special_dates(@employee) # Call the balance calculator for all time off types as of today as_of_date = if params[:calculator_date].present? Date.parse(params[:calculator_date]) elsif params[:start_date].present? Date.parse(params[:start_date]) else Date.current end @time_off_balances_view = TimeOffBalanceCalculator.new(employee: @employee, date: as_of_date).formatted_balances else redirect_to user_time_off_path(@employee), error: "#{@employee.full_name} doesn't have an active work schedule." end end |
#retrieve_date_details ⇒ void
This method returns an undefined value.
AJAX endpoint: computes the request-date breakdown (available dates,
overlaps, time available) for the given date range and type.
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 |
# File 'app/controllers/crm/time_off_requests_controller.rb', line 146 def retrieve_date_details start_date = Date.parse(params[:start_date]) end_date = Date.parse(params[:end_date]) time_off_type_id = params[:time_off_type] employee_id = params[:employee_id] time_off_request_id = params[:time_off_request_id] # Validate that required parameters are present if start_date && end_date && time_off_type_id && employee_id result = TimeOffRequest.generate_request(start_date, end_date, time_off_type_id, employee_id, time_off_request_id) if result[:error].present? render json: { error: result[:error], dates: [] }, status: :unprocessable_content else render json: { dates: result[:dates], overlapping_dates: result[:overlapping_dates], time_available_for_request: result[:time_available_for_request] } end else render json: { error: 'Missing time off request parameters' }, status: :unprocessable_content end end |
#show ⇒ void
This method returns an undefined value.
Shows a request with its blocked dates, holidays, conflicts, and
Google Calendar sync status.
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'app/controllers/crm/time_off_requests_controller.rb', line 23 def show @time_off_request = TimeOffRequest.includes(:employee, :time_off_request_dates).find(params.expect(:id)) @employee = @time_off_request.employee @blocked_dates = fetch_blocked_dates(@time_off_request) @company_holidays = fetch_holidays(@time_off_request) @conflicting_requests = fetch_conflicting_requests(@time_off_request) @work_schedule = @employee.work_schedules.effective_now.first @google_calendar_event = TimeOffRequests::GoogleCalendar.new(@time_off_request).fetch_event if @time_off_request.google_event_id.present? google_auth_status = TimeOffRequests::GoogleAuthService.check_status(@employee) @is_own_request = current_user&.id == @employee.id @has_auth_error = google_auth_status[:needs_reconnect] || (@google_calendar_event.present? && @google_calendar_event[:error].present? && @google_calendar_event[:error].to_s.downcase.match?(/authoriz|reconnect|expired/)) @time_off_types_by_name = if @time_off_request.balance_snapshot.present? TimeOffType.where(name: @time_off_request.balance_snapshot.keys).index_by(&:name) else {} end end |
#sync_google_calendar ⇒ void
This method returns an undefined value.
Pushes/pulls the request's Google Calendar event and redirects with
the result.
170 171 172 173 174 175 176 177 178 179 180 181 |
# File 'app/controllers/crm/time_off_requests_controller.rb', line 170 def sync_google_calendar @time_off_request = TimeOffRequest.find(params.expect(:id)) @employee = @time_off_request.employee result = TimeOffRequests::GoogleCalendar.new(@time_off_request).sync_event if result[:success] redirect_to time_off_request_path(@time_off_request), notice: result[:message] else redirect_to time_off_request_path(@time_off_request), alert: result[:error] end end |
#update ⇒ void
This method returns an undefined value.
Updates the request loaded by #prevent_past_edits (never lets the
employee change).
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 |
# File 'app/controllers/crm/time_off_requests_controller.rb', line 123 def update @time_off_request = TimeOffRequest.find(params.expect(:id)) @employee = @time_off_request.employee @work_schedule = @time_off_request.employee.work_schedules.effective_now.first # A request never moves between employees — ignore any employee_id sent. if @time_off_request.update(params[:time_off_request].except(:employee_id)) if @time_off_request.google_calendar_error.present? flash[:alert] = @time_off_request.google_calendar_error else flash[:notice] = 'Request successfully updated.' end redirect_to user_time_off_path(@employee, tab: "time_off_requests") else flash.now[:alert] = "Errors present: #{@time_off_request.errors..to_sentence}" render :edit, status: :unprocessable_content end end |