require 'old_sql/report_design/parser' require 'old_sql/report_design/model' require 'old_sql/report_design/row' require 'old_sql/report_design/cell' require 'old_sql/report_design/cell_data' require 'old_sql/report_design/chart_parser' require 'old_sql/report_design/chart' require 'old_sql/report_design/chart_item' require 'old_sql/report_design/chart_data' module OldSql module ReportProcessor class Base ROUND_PRECISION = OldSql.rounding_precision def execute_query(report_config, start_date, end_date, query_vars = nil) sql = load_sql(report_config['report_sql'], start_date, end_date, query_vars) query(sql, report_config) return nil if @resultset.nil? init report_design = report_config['report_design'] if report_design parse_design(report_design, @resultset) if report_design =~ /csv/ parse_chart_design(report_design, @resultset) if report_design =~ /yml/ else loaded_sub_processor = load_sub_processor(report_config['report_processor']) if loaded_sub_processor.nil? parse(@resultset) else @data = loaded_sub_processor.parse(@resultset) end end @data end protected def add_row(cell_data = [], id = @id+1) @data[:rows] << {id: id, cell: cell_data} end def round(value, precision = ROUND_PRECISION) factor = 10.0**precision (value*factor).round / factor end def isNumeric(s) Float(s) != nil rescue false end private def load_sql(report_sql, start_date, end_date, query_vars) vars = {:start_date => start_date, :end_date => end_date} if !query_vars.nil? vars = vars.merge query_vars end template = File.read("#{Rails.root}/config/old_sql/report_sql/#{report_sql}.erb") sql = Erubis::Eruby.new(template).result(vars) end def query sql, report_config begin #todo change to a reporting db db = db_connection(report_config['report_db']) raise Exception("Unable to Establish a Database Connection") unless db.active? @resultset = [] rec = db.select_all(sql) rec.each do |row| @resultset << row end rescue Exception=>e Rails.logger.error e end @resultset end def db_connection report_db db = nil if report_db.nil? db = ActiveRecord::Base.connection(); else require report_db db_class_name = "" first = true report_db.split("/").each do |path| db_class_name << "::" unless first path.split("_").each {|c| db_class_name << c.capitalize } first = false end db=eval(db_class_name).connection end db end def load_sub_processor sub_processor return if sub_processor.nil? loaded_sub_processor = nil begin require "old_sql/report_processor/#{sub_processor.downcase}" loaded_sub_processor=eval("OldSql::ReportProcessor::#{sub_processor.gsub("_","")}").new rescue Exception=>e Rails.logger.error e.message end loaded_sub_processor end def init @rec = @resultset[0] @id = 0 @data = {} @data[:rows] = [] init_jqgrid_data end def init_jqgrid_data(page=1, total=1, records=1) @data[:page]=page @data[:total]=total @data[:records]=records end def parse(resultset) init_jqgrid_data resultset.each do |r| cell = [] r.each do |key, value| cell << value end add_row(cell) end @data end def parse_design(design, resultset) model = OldSql::ReportDesign::Parser.read_file("#{design}") model.rows.each do |row| report_row = [] row.cells.each do |cell| expression = "" cell.cell_data.each do |cd| if cell.expression? if cd.type == OldSql::ReportDesign::CellData::COLUMN expression << @rec[cd.data].to_s elsif cd.type == OldSql::ReportDesign::CellData::OPERATOR || cd.type == OldSql::ReportDesign::CellData::NUMERIC_LITERAL expression << cd.data end else if cd.type == OldSql::ReportDesign::CellData::COLUMN result = @rec[cd.data] if OldSql.round_report_values result = round(result.to_f, OldSql.rounding_precision) end report_row << result elsif cd.type == OldSql::ReportDesign::CellData::LABEL report_row << cd.data.gsub(/"/,"") end end end report_row << eval_expression(expression) unless expression.length==0 end add_row(report_row) end end def parse_chart_design(design, resultset) report_row = [] chart = OldSql::ReportDesign::ChartParser.read_file("#{design}") chart.items.each do |item| key = item.key expression = "" item.chart_data.each do |data| if item.expression? if data.type == OldSql::ReportDesign::ChartData::COLUMN expression << @rec[data.value].to_s elsif data.type == OldSql::ReportDesign::ChartData::OPERATOR || data.type == OldSql::ReportDesign::ChartData::NUMERIC_LITERAL expression << data.value end else if data.type == OldSql::ReportDesign::ChartData::COLUMN result = @rec[data.value] if OldSql.round_report_values result = round(result.to_f, OldSql.rounding_precision) end report_row << [key,result] end end end report_row << [key,eval_expression(expression)] unless expression.length==0 end @data = {chart.type=>report_row} end def eval_expression expression result = 0.0 begin result = eval(expression) rescue ZeroDivisionError => e rescue Exception => e end if result.class == Float || result.class == Fixnum result = result.to_s end if result == "Infinity" || result == "NaN" result = 0.0 elsif OldSql.round_report_values result = round(result.to_f, OldSql.rounding_precision) end result end end end end