Created
January 20, 2016 16:01
-
-
Save arabyniuk/ee2e1021673d7f60eb7f to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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