# -*- coding: utf-8 -*-
#
#= モデル共通
# Authors:: Sumiyo Yamamoto
# Copyright:: Copyright (C) OrbusNeich Medical K.K.  2010.
#--
# date        name                   note
# 2010.2.26   Sumiyo Yamamoto        新規作成
#-------------------------------------------------------------------------------
#++
module Comm
  module BaseModel
    #= 基本モデルクラス
    # 全てのモデルが継承する、ベースとなるモデル。
    #------------------------------------------------------------------------#++
    class General < ActiveRecord::Base
      attr_reader :master_rev
      # 抽象クラス設定（対応するテーブルが存在しない）
      self.abstract_class = true
      
      #== named_scope
      #-----------------------------------------------------------------#++
      named_scope :asign, lambda {|key, vals|
        if vals.class != Array
          vals = [vals]
        end
        if vals.length > 0
          if vals.first.class == String && !(key.to_s =~ /(.+)(_id|_code)$/)
            condition_array = []
            vals.each do |val|
              condition_array.push("#{key} LIKE '%#{val}%'")
            end
            {:conditions => "(#{condition_array.join(' OR ')})"}
          else
            {:conditions => "#{key} IN (#{vals.join(',')})"}
          end
        else
          {:conditions => '1 = 0'}
        end
      }
      
      named_scope :passign, lambda {|key, vals|
        if vals.class == Array
          if vals.length > 0
          if vals.first.class == String && !(key.to_s =~ /(.+)(_id|_code)$/)
              condition_array = []
              vals.each do |val|
                condition_array.push("#{key} LIKE '%#{val}%'")
              end
              {:conditions => "(#{condition_array.join(' OR ')})"}
            else
              {:conditions => "#{key} IN (#{vals.join(',')})"}
            end
          else
            {}
          end
        elsif vals.class == String
          {:conditions => "#{key} IN (#{vals})"}
        else
          {}
        end
      }
      
      named_scope :sassign, lambda {|key, val|
        if val
          {:conditions => "#{key} = #{val}"}
        else
          {}
        end
      }
      
      named_scope :select_disp, :select => 'id, disp_name'
      
      named_scope :select_id, :select => 'id'
      
      named_scope :selekt, lambda {|cols|
        if cols.class != Array
          cols = [cols]
        end
        {:select => cols.join(',')}
      }
      
      named_scope :not_blank, lambda {|col|
        {:conditions => "#{col} IS NOT NULL AND #{col} != ''"}
      }

      named_scope :blank, lambda {|col|
        {:conditions => "#{col} IS NULL"}
      }
      
      named_scope :ordr, lambda {|col|
        {:order => col}
      }

      #== 登録実行管理
      #-----------------------------------------------------------------#++
      def create_mng(params, rev_number = nil)
        @result = true
        begin
          self.transaction do
            ret = create_exec(params)
            unless ret
              raise Exception
            end
            # リビジョンチェック
            rev_result, master_rev = MasterRevision.check_rev_number(rev_number)
            unless rev_result
              @master_rev = {:master_rev => master_rev,
                             :tables => MasterRevision.get_table_names(rev_number)}
              j_names = []
              @master_rev[:tables].each{|name| j_names << Menu.get_disp_name(name)}
              raise MasterRevisionError, EMJ0010+EMD0008+"<br><br>"+j_names.join(',')
            end
          end
        rescue UserOperationError => e
          if errors.empty?
            errors.add_to_base(e.message)
          end
          logger.error(error_out(e))
          @result =  false
        rescue Exception => e
          dead_lock_replace(e)
          if errors.empty?
            errors.add_to_base(EMJ0001 + e)
          end
          logger.error(error_out(e))
          @result =  false
        end
        @result
      end

      #== 更新実行管理
      #-----------------------------------------------------------------#++
      def update_mng(params, rev_number = nil)
        @result = true
        begin
          self.transaction do
            ret = update_exec(params)
            unless ret
              raise Exception
            end
            # リビジョンチェック
            rev_result, master_rev = MasterRevision.check_rev_number(rev_number)
            unless rev_result
              @master_rev = {:master_rev => master_rev,
                             :tables => MasterRevision.get_table_names(rev_number)}
              j_names = []
              @master_rev[:tables].each{|name| j_names << Menu.get_disp_name(name)}
              raise MasterRevisionError, EMJ0010+EMD0008+"<br><br>"+j_names.join(',')
            end
          end
        rescue UserOperationError => e
          if errors.empty?
            errors.add_to_base(e.message)
          end
          logger.error(error_out(e))
          @result =  false
        rescue Exception => e
          dead_lock_replace(e)
          if errors.empty?
            errors.add_to_base(EMJ0001 + e)
          end
          logger.error(error_out(e))
          @result =  false
        end
        @result
      end

      #== 削除実行管理
      #-----------------------------------------------------------------#++
      def destroy_mng
        @result = true
        begin
          self.transaction do
            ret = destroy_exec
            unless ret
              raise Exception
            end
          end
        rescue UserOperationError => e
          if errors.empty?
            errors.add_to_base(e.message)
          end
          logger.error(error_out(e))
          @result =  false
        rescue Exception => e
          dead_lock_replace(e)
          if errors.empty?
            errors.add_to_base(EMJ0001 + e)
          end
          logger.error(error_out(e))
          @result =  false
        end
        @result
      end

      #== 登録処理実行
      #-----------------------------------------------------------------#++
      def create_exec(params = {})
        result = true
        self.attributes = params
        ret = save
        unless ret
          result = false
          errors.add_to_base(EMJ0003 + EMD0004 + "(#{self.class.to_s})")
        end
        result
      end

      #== 更新処理実行
      #-----------------------------------------------------------------#++
      def update_exec(params = {})
        result = true
        ret = self.update_attributes(params)
        unless ret
          result = false
          errors.add_to_base(EMJ0003 + EMD0004 + "(#{self.class.to_s})")
        end
        result
      end

      #== 削除処理実行
      #-----------------------------------------------------------------#++
      def destroy_exec
        result = true
        destroy
        result
      end
      
      #== 1カラム更新
      #-----------------------------------------------------------------#++
      def update_item(name, val)
        ret = update_attribute(name, val)
        return ret ? true : false
      end
      
      # エラーログ出力
      def error_out(e)
        errors = ["\n>>>>> ERROR INFO"]
        errors << Time.now.to_s
        errors << e.message
        errors << @session.inspect if @session
        errors << e.backtrace
        return errors.join("\n")
      end
      # デッドロックの検出
      def dead_lock_replace(e)
        if e.message =~ /(.*)Deadlock found when trying to get lock(.*)/
          errors.add_to_base(EMJ0012 + EMD0017)
        end
      end
    end
  end
end
