module CommLogistics::Modules::SetParams
  #table_params, detail_paramsをセットするメソッド
  attr_reader :table_params, :detail_params, :set_params_success
  attr_accessor :table_rel
  @@common_detail_columns = "product_category_id,product_set_id,product_id,lot_number,serial_number,ubd,validity_period,unit_code,quantity,stock_type_code,detail_note,stock_flag_code"
  def set_params(parent_ar, params)
    #non_stockのものが抜けたりするので、最後にseq_numberをつける。
    @table_rel ||= {} #table_relが入っていないことも一応考慮
    @table_params = set_table_params(parent_ar, params)
    @detail_params = add_seq_number_to_detail_params(set_detail_params(parent_ar, @table_params, params))
    @set_params_success = check_set_details(@detail_params)
    return @set_params_success
  rescue UserOperationError => e
    @set_params_success = false
    raise e
  rescue Exception => e
    Rails.logger.error('set_params error:'+e.message+"\n"+e.backtrace.join("\n"))
    @set_params_success = false
    raise "システムエラーです。OSSにお問い合わせください。\n"+e.message
  end
 
  #親パラメータを作成するメソッド 
  def set_table_params(parent_ar,params)
    require 'config/site_config.rb'
    table_params = HashWithIndifferentAccess.new #Hash.new
    parent_keys_array = AcceptOrder.column_names
    class_keys_hash = self.class.columns_hash
    #存在するキーをセットしていく 
    parent_keys_array.each do |key|
      table_params[key.to_sym] = parent_ar[key].to_s unless class_keys_hash[key].blank?  
    end
    #親データのidをセットする。
    table_params[:accept_order_id] = parent_ar.id
    #type_code/trigger_codeをセットする。
    add_trans_code_to_table_params(parent_ar, table_params)
    #リビジョンを1とする。
    table_params[:rev_number] = 1
    #sale_sheet_note, shipping_sheet_noteなどの伝票備考
    table_params[(self.class.to_s.underscore + '_note').to_sym] = parent_ar.accept_order_note unless class_keys_hash[self.class.to_s.underscore + '_note'].blank?
    #total_quantityをセットする。
    set_table_params_for_total_quantity(parent_ar,table_params)
    #自動フロー日時をセット
    table_params[:auto_flow_at] = DateTime.now.to_s
    #各取引の処理日を操作日とする場合。
    if $AUTO_FLOW_CURRENT_DATE_FOR_TRANS
      table_params[:target_date] = Date.today.to_s
    end
    table_params[:input_date] = Date.today.to_s
    
    #必要ないキーを削除する
    table_params.delete(:id)
    table_params.delete(:created_at)
    table_params.delete(:updated_at)
    table_params.delete(:deleted_at)
    return table_params
  end
  
  def set_table_params_for_total_quantity(parent_ar,table_params)
    #売上以外は、基本、非在庫品はいらない。つまり、total_quantity=stock_total_quantityとなる。
    table_params[:total_quantity] = parent_ar.stock_total_quantity.to_i
  end
  
  def add_trans_code_to_table_params(parent_ar, table_params)
    base_name = self.class.to_s.underscore
    trans_type_col_name = base_name + '_type_code'
    trans_trigger_col_name = base_name + '_trigger_code'
    column_names = self.class.column_names
    # hogehoge_type_codeの設定
    if !@table_rel['trans_type_code'].blank? && column_names.include?(trans_type_col_name)
      table_params[trans_type_col_name.to_sym] = @table_rel['trans_type_code']
    end
    # hogehoge_trigger_codeの設定
    if column_names.include?(trans_trigger_col_name)
      parent_code = parent_ar.accept_order_trigger_code.to_i
      if parent_code==Comm::Const::MasterCode::MCODE_ACCEPT_ORDER_TRIGGER_SALES_AND_STOCKS
        table_params[trans_trigger_col_name.to_sym]=eval('Comm::Const::MasterCode::MCODE_' + base_name.upcase + '_TRIGGER_MANAGEMENT')
      elsif parent_code==Comm::Const::MasterCode::MCODE_ACCEPT_ORDER_TRIGGER_SALES_ONLY
        table_params[trans_trigger_col_name.to_sym]=eval('Comm::Const::MasterCode::MCODE_' + base_name.upcase + '_TRIGGER_THROUGH')
      end
    end
  end
  #納品先マスターに出荷元倉庫が設定されていたらそれを優先する。
  def add_own_warehouse_to_table_params(table_params, params)
    if params[:own_warehouse_id].blank?
      warehouse_ar = Warehouse.find(table_params[:warehouse_id].to_i)
      if warehouse_ar.own_warehouse_id.blank?
        table_params[:own_warehouse_id] = App::Const::SystemCode::DEFAULT_OWN_WAREHOUSE_ID || 1
      else
        table_params[:own_warehouse_id] = warehouse_ar.own_warehouse_id
      end
    else
      table_params[:own_warehouse_id] = params[:own_warehouse_id].to_i
    end
  end
  
  #明細情報のデータを作成するメソッド=>各モデルでオーバーライド
  def set_detail_params(parent_ar, table_params, params)
    return []
  end
  #受注に紐づけられた出荷IDを取得するメソッド=>注文買取/注文サンプルで使う
  def get_shipping_rels(parent_ar, columns)
    shippings = Shipping.find(:all, :conditions=>["accept_order_id=? AND invalid_flag_code=? AND shipping_state_code=?", parent_ar.id, Comm::Const::MasterCode::MCODE_FLAG_OFF, Comm::Const::MasterCode::MCODE_SHIPPING_STATE_COMP]).map{|ar|ar.id}
    return ShippingDetail.find(:all, :conditions=>"shipping_id in (#{shippings.join(',')})", :select => columns.sub(',stock_type_code',",#{Comm::Const::MasterCode::MCODE_STOCK_TYPE_LONG} AS stock_type_code"))
  end
  

  #シーケンスナンバーを補完する
  def add_seq_number_to_detail_params(details)
    seq_number = 1
    details.each do |d|
      d['seq_number'] = seq_number
      seq_number = seq_number + 1
    end
  end
  
  #全てのdetailが必要な値を持っているかチェック。UBDだけチェックすればよい。
  def check_set_details(detail_params)
    error_container = []
    detail_params.each do |detail|
      if detail['ubd'].blank? && detail['stock_flag_code']==Comm::Const::MasterCode::MCODE_STOCK_FLAG_ON
        error_container << detail['product_id']
      end
    end
    unless error_container.empty?
      ars = Product.find_by_sql(["SELECT id, disp_name FROM products WHERE id IN (?)", error_container.uniq])
      emsg = []
      ars.each{|ar| emsg << " 製品ID:"+ar.id.to_s+" 型番名:"+ar.disp_name}
      raise UserOperationError, "次の製品型番のパラメータが作製できません。在庫などを再確認してください。\n"+emsg.join("\n")
    end
    return detail_params.length > 0
  end

end

