app/controllers/admin/theft_alerts_controller.rb
class Admin::TheftAlertsController < Admin::BaseController
include SortableTable
before_action :set_period, only: [:index]
before_action :find_theft_alert, only: [:edit, :update]
def index
@theft_alerts =
searched_theft_alerts.reorder("theft_alerts.#{sort_column} #{sort_direction}")
.includes(:theft_alert_plan, :stolen_record)
.page(params.fetch(:page, 1))
.per(params.fetch(:per_page, 25))
@page_title = "Admin | Promoted alerts"
@location_counts = InputNormalizer.boolean(params[:search_location_counts])
end
def show
redirect_to edit_admin_theft_alert_path
end
def edit
end
def update
if InputNormalizer.boolean(params[:activate_theft_alert])
new_data = @theft_alert.facebook_data || {}
@theft_alert.update(facebook_data: new_data.merge(activating_at: Time.current.to_i))
ActivateTheftAlertWorker.perform_async(@theft_alert.id, true)
flash[:success] = "Activating, please wait"
redirect_to admin_theft_alert_path(@theft_alert)
elsif InputNormalizer.boolean(params[:update_theft_alert])
UpdateTheftAlertFacebookWorker.new.perform(@theft_alert.id)
flash[:success] = "Updating Facebook data"
redirect_to admin_theft_alerts_path
elsif @theft_alert.update(permitted_update_params)
flash[:success] = "Success!"
redirect_to admin_theft_alerts_path
else
flash[:error] = @theft_alert.errors.to_a
render :edit
end
end
def new
@bike = Bike.unscoped.find_by_id(params[:bike_id])
unless @bike.present?
flash[:info] = "Unable to find that bike. Select a bike to create a new promoted alert"
redirect_to admin_theft_alerts_path
return
end
@stolen_record = @bike.current_stolen_record
@theft_alerts = @stolen_record&.theft_alerts || []
bike_image = PublicImage.find_by(id: params[:selected_bike_image_id])
@bike.current_stolen_record.generate_alert_image(bike_image: bike_image)
@theft_alert_plans = TheftAlertPlan.active.price_ordered_asc.in_language(I18n.locale)
@theft_alert = TheftAlert.new(stolen_record: @stolen_record,
theft_alert_plan: @theft_alert_plans.first,
user: current_user,
admin: true)
@theft_alert.set_calculated_attributes # Set some stuff
end
def create
@theft_alert = TheftAlert.new(permitted_create_params)
if @theft_alert.save
ActivateTheftAlertWorker.perform_async(@theft_alert.id) if @theft_alert.activateable?
flash[:success] = "Promoted alert created!"
redirect_to edit_admin_theft_alert_path(@theft_alert)
else
render :new
end
end
helper_method :searched_theft_alerts, :available_statuses, :available_paid_admin
private
def find_theft_alert
@theft_alert ||= TheftAlert.find(params[:id])
@stolen_record ||= @theft_alert.stolen_record
@bike ||= Bike.unscoped.find(@stolen_record.bike_id)
end
def permitted_update_params
params.require(:theft_alert).permit(:notes)
end
def permitted_create_params
params.require(:theft_alert).permit(:notes,
:stolen_record_id,
:ad_radius_miles,
:theft_alert_plan_id)
.merge(user: current_user, admin: true)
end
# Override, set one week before earliest created theft alert
def earliest_period_date
if @search_facebook_data
Time.at(1624982189)
else
Time.at(1560805519)
end
end
def sortable_columns
%w[created_at theft_alert_plan_id amount_cents_facebook_spent reach status start_at end_at]
end
def available_statuses
TheftAlert.statuses + ["posted"]
end
def available_paid_admin
%w[paid admin paid_or_admin]
end
def searched_theft_alerts
@search_recovered = InputNormalizer.boolean(params[:search_recovered])
theft_alerts = if @search_recovered
stolen_record_ids = StolenRecord.recovered.with_theft_alerts
.where(theft_alerts: {created_at: @time_range}).pluck(:id)
TheftAlert.where(stolen_record_id: stolen_record_ids)
else
TheftAlert
end
@search_paid_admin = available_paid_admin.include?(params[:search_paid_admin]) ? params[:search_paid_admin] : nil
theft_alerts = theft_alerts.send(@search_paid_admin) if @search_paid_admin.present?
@search_facebook_data = InputNormalizer.boolean(params[:search_facebook_data])
theft_alerts = theft_alerts.facebook_updateable if @search_facebook_data
if available_statuses.include?(params[:search_status])
@status = params[:search_status]
theft_alerts = if @status == "posted"
theft_alerts.posted
else
theft_alerts.where(status: @status)
end
else
@status = "all"
end
if params[:user_id].present?
@user = User.unscoped.friendly_find(params[:user_id])
theft_alerts = theft_alerts.where(user_id: @user.id) if @user.present?
end
if params[:search_bike_id].present?
@bike = Bike.unscoped.friendly_find(params[:search_bike_id])
theft_alerts = theft_alerts.where(bike_id: @bike.id) if @bike.present?
end
# We always render distance
distance = params[:search_distance].to_i
@distance = distance.present? && distance > 0 ? distance : 50
if params[:search_location].present?
bounding_box = Geocoder::Calculations.bounding_box(params[:search_location], @distance)
theft_alerts = theft_alerts.within_bounding_box(bounding_box)
end
# Only handling created_at now
@time_range_column ||= "created_at"
theft_alerts.where(@time_range_column => @time_range)
end
# Deprecated - should be removed soon.
def set_alert_timestamps(theft_alert_attrs)
currently_pending = @theft_alert.status == "pending"
transitioning_to_active = theft_alert_attrs[:status] == "active"
transitioning_to_pending = theft_alert_attrs[:status] == "pending"
if currently_pending && transitioning_to_active
theft_alert_plan = TheftAlertPlan.find(theft_alert_attrs[:theft_alert_plan_id])
now = Time.current
theft_alert_attrs[:start_at] = now
theft_alert_attrs[:end_at] = now + theft_alert_plan.duration_days.days
elsif transitioning_to_pending
theft_alert_attrs[:start_at] = nil
theft_alert_attrs[:end_at] = nil
else
timezone = TimeParser.parse_timezone(params[:timezone])
theft_alert_attrs[:start_at] = TimeParser.parse(theft_alert_attrs[:start_at], timezone)
theft_alert_attrs[:end_at] = TimeParser.parse(theft_alert_attrs[:end_at], timezone)
end
theft_alert_attrs
end
end