Skip to content

Instantly share code, notes, and snippets.

@arabyniuk
Created January 20, 2016 16:01
Show Gist options
  • Save arabyniuk/ee2e1021673d7f60eb7f to your computer and use it in GitHub Desktop.
Save arabyniuk/ee2e1021673d7f60eb7f to your computer and use it in GitHub Desktop.
class MachineMapsBoard < BasicBoard
def machines
@machines ||= machines_in_regions.find_all do |m|
m.was_available_in_time_range(from_date: from_time.to_date,
to_date: to_time.to_date)
end
end
def selected_machine_groups
if machine_groups_ids.any?
company.machine_groups.where(id: machine_groups_extra_ids)
else
company.machine_groups
end
end
def machines_in_regions
machines_in_regions =
Machine.active_machines_in_regions(regions_to_show_id)
.includes(:inventory_history_items)
.includes(:machine_group)
.includes(:machine_region_mapping_items)
.includes(:gps_logger_mapping_items)
.includes(data_source_filter_by_now_gps_loggers: {
gps_logger: :last_current_data_items })
if machine_groups_extra_ids.present?
machines_in_regions = machines_in_regions.where(machine_group_id: needed_ids)
end
machines_in_regions.to_a
end
def machines_data_on_map
@machines_data_on_map = []
@machines_grouped_no_gps_data = []
machines.each do |machine|
gps_data = proccess_machine_data_on_map(machine)
if gps_data.present?
@machines_data_on_map << machine.gps_data_geojson_hash(gps_data)
else
@machines_grouped_no_gps_data << machine
end
end
# try to get any last position, if last data earlier than current date
@machines_grouped_no_gps_data.each do |machine|
proccess_machine_data_on_map_without_data(machine)
end
@machines_data_on_map
end
def show_machines_without_group
@show_machines_without_group ||=
(show_machines_without_group? || machine_groups_ids.blank?) || nil
end
private
def needed_ids
needed_ids = selected_machine_groups.map(&:id)
needed_ids << nil if show_machines_without_group
needed_ids
end
def show_machines_without_group?
machine_groups_ids.include?(0)
end
def machine_groups_extra_ids
machine_groups_ids - [0]
end
def machine_groups_ids
params.fetch(:machine_groups, "").split(',').map(&:to_i)
end
def proccess_machine_data_on_map(machine)
gps_data_items = gps_data_items(machine).flatten
return if gps_data_items.blank? || gps_data_items[0].blank? # [nil]
gps_data = machine.create_gps_data_hash_from_hour_data_items(gps_data_items)
gps_data
end
def gps_data_items(machine)
machine_data_source_gps_loggers_by_range(machine).map do |dsgl|
gps_data_item_metadata(dsgl)
end
end
def machine_data_source_gps_loggers_by_range(machine)
data_source_gps_loggers_by_range.find_all do |ds|
ds.mappable_id == machine.id
end
end
def gps_data_item_metadata(dsgl)
logger = dsgl.try(:gps_logger)
return unless logger
gps_logger_current_data_item_by_range.find_all do |x|
x.gps_logger_metadata_item_id == logger.id
end
end
def proccess_machine_data_on_map_without_data(machine)
gps_last_data = gps_last_data(machine)
return if gps_last_data.blank?
@machines_data_on_map << machine.gps_data_geojson_last_point_hash(gps_last_data)
end
def gps_last_data(machine)
machine_data_source_gps_loggers_last_data =
machine_data_source_gps_loggers_last_data(machine)
if machine_data_source_gps_loggers_last_data
logger = machine_data_source_gps_loggers_last_data.try(:gps_logger)
current_gps_data_item = current_gps_data_item(logger) if logger
end
return unless current_gps_data_item.present?
machine.create_gps_data_hash_from_hour_data_items([current_gps_data_item])
end
def machine_data_source_gps_loggers_last_data(machine)
data_source_gps_loggers_last_data.find do |ds|
ds.mappable_id == machine.id
end
end
def current_gps_data_item(logger)
gps_logger_current_data_item_last_data.find do |x|
x.gps_logger_metadata_item_id == logger.id
end
end
def subquery_dsgl
DataSourceGpsLogger
.select('mappable_id, MAX(start_time) as max_start_time')
.group(:mappable_id).to_sql
end
def data_source_gps_loggers_last_data
DataSourceGpsLogger
.where("ds.mappable_id IN (#{machines_grouped_no_gps_data_ids})")
.select('id, start_time, end_time, gps_logger_id, ds.mappable_id')
.joins("ds INNER JOIN (#{subquery_dsgl}) inds
ON inds.mappable_id = ds.mappable_id
AND inds.max_start_time = ds.start_time")
.where_time_range(DateTime.new(2000, 1, 1), before_time)
.includes(:gps_logger).to_a
end
def data_source_gps_loggers_select_fields
data_source_gps_loggers_last_data.map do |x|
[x.gps_logger_id.to_s, x.end_time.try(:to_date).to_s]
end.to_s.tr('"', "'")
end
def current_data_ids
GpsLoggerCurrentDataItem.connection.execute(
"SELECT * FROM #{tenant}.get_current_gps_data_ids_by_end_time(
ARRAY#{data_source_gps_loggers_select_fields}) AS (id int)")
.to_a.map { |x| x['id'] }
end
def gps_logger_current_data_item_last_data
GpsLoggerCurrentDataItem.where(id: current_data_ids).to_a
end
def machines_grouped_no_gps_data_ids
@machines_grouped_no_gps_data_ids ||=
@machines_grouped_no_gps_data.map(&:id).join(', ')
end
def data_source_gps_loggers_by_range
DataSourceGpsLogger.where(mappable_id: machines.map(&:id))
.where_time_range(from_time, to_time)
.includes(:gps_logger).to_a
end
def dsgl_by_range_gps_logger_ids
data_source_gps_loggers_by_range.collect { |x| x.try(:gps_logger).try(:id) }
end
def gps_logger_current_data_item_by_range
GpsLoggerCurrentDataItem
.where(gps_logger_metadata_item_id: dsgl_by_range_gps_logger_ids)
.select([:id, :hour_start, :distance, :last_time, :max_speed,
:gps_logger_metadata_item_id, :all_data_records,
:event_data, :current_data_record])
.where_time_range(range_start_time, range_end_time).to_a
end
def before_time
Time.zone.now
end
def range_start_time
min_start_time ? [hour_start, min_start_time].max : hour_start
end
def range_end_time
max_end_time ? [hour_end, max_end_time].min : hour_end
end
def hour_start
from_time.utc.beginning_of_hour
end
def hour_end
(to_time.utc - 1.second).end_of_hour
end
def min_start_time
data_source_gps_loggers_by_range.map(&:start_time).min
end
def max_end_time
data_source_gps_loggers_by_range.map(&:end_time).compact.max
end
def tenant
Apartment::Tenant.current
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment